You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

289 lines
7.1 KiB

9 years ago
9 years ago
4 years ago
6 years ago
9 years ago
9 years ago
  1. package topology
  2. import (
  3. "fmt"
  4. "github.com/seaweedfs/seaweedfs/weed/glog"
  5. "github.com/seaweedfs/seaweedfs/weed/pb"
  6. "github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
  7. "github.com/seaweedfs/seaweedfs/weed/storage"
  8. "github.com/seaweedfs/seaweedfs/weed/storage/needle"
  9. "github.com/seaweedfs/seaweedfs/weed/storage/types"
  10. "github.com/seaweedfs/seaweedfs/weed/util"
  11. )
  12. type DataNode struct {
  13. NodeImpl
  14. Ip string
  15. Port int
  16. GrpcPort int
  17. PublicUrl string
  18. LastSeen int64 // unix time in seconds
  19. Counter int // in race condition, the previous dataNode was not dead
  20. }
  21. func NewDataNode(id string) *DataNode {
  22. dn := &DataNode{}
  23. dn.id = NodeId(id)
  24. dn.nodeType = "DataNode"
  25. dn.diskUsages = newDiskUsages()
  26. dn.children = make(map[NodeId]Node)
  27. dn.NodeImpl.value = dn
  28. return dn
  29. }
  30. func (dn *DataNode) String() string {
  31. dn.RLock()
  32. defer dn.RUnlock()
  33. return fmt.Sprintf("Node:%s, Ip:%s, Port:%d, PublicUrl:%s", dn.NodeImpl.String(), dn.Ip, dn.Port, dn.PublicUrl)
  34. }
  35. func (dn *DataNode) AddOrUpdateVolume(v storage.VolumeInfo) (isNew, isChangedRO bool) {
  36. dn.Lock()
  37. defer dn.Unlock()
  38. return dn.doAddOrUpdateVolume(v)
  39. }
  40. func (dn *DataNode) getOrCreateDisk(diskType string) *Disk {
  41. c, found := dn.children[NodeId(diskType)]
  42. if !found {
  43. c = NewDisk(diskType)
  44. dn.doLinkChildNode(c)
  45. }
  46. disk := c.(*Disk)
  47. return disk
  48. }
  49. func (dn *DataNode) doAddOrUpdateVolume(v storage.VolumeInfo) (isNew, isChangedRO bool) {
  50. disk := dn.getOrCreateDisk(v.DiskType)
  51. return disk.AddOrUpdateVolume(v)
  52. }
  53. // UpdateVolumes detects new/deleted/changed volumes on a volume server
  54. // used in master to notify master clients of these changes.
  55. func (dn *DataNode) UpdateVolumes(actualVolumes []storage.VolumeInfo) (newVolumes, deletedVolumes, changeRO []storage.VolumeInfo) {
  56. actualVolumeMap := make(map[needle.VolumeId]storage.VolumeInfo)
  57. for _, v := range actualVolumes {
  58. actualVolumeMap[v.Id] = v
  59. }
  60. dn.Lock()
  61. defer dn.Unlock()
  62. existingVolumes := dn.getVolumes()
  63. for _, v := range existingVolumes {
  64. vid := v.Id
  65. if _, ok := actualVolumeMap[vid]; !ok {
  66. glog.V(0).Infoln("Deleting volume id:", vid)
  67. disk := dn.getOrCreateDisk(v.DiskType)
  68. delete(disk.volumes, vid)
  69. deletedVolumes = append(deletedVolumes, v)
  70. deltaDiskUsages := newDiskUsages()
  71. deltaDiskUsage := deltaDiskUsages.getOrCreateDisk(types.ToDiskType(v.DiskType))
  72. deltaDiskUsage.volumeCount = -1
  73. if v.IsRemote() {
  74. deltaDiskUsage.remoteVolumeCount = -1
  75. }
  76. if !v.ReadOnly {
  77. deltaDiskUsage.activeVolumeCount = -1
  78. }
  79. disk.UpAdjustDiskUsageDelta(deltaDiskUsages)
  80. }
  81. }
  82. for _, v := range actualVolumes {
  83. isNew, isChangedRO := dn.doAddOrUpdateVolume(v)
  84. if isNew {
  85. newVolumes = append(newVolumes, v)
  86. }
  87. if isChangedRO {
  88. changeRO = append(changeRO, v)
  89. }
  90. }
  91. return
  92. }
  93. func (dn *DataNode) DeltaUpdateVolumes(newVolumes, deletedVolumes []storage.VolumeInfo) {
  94. dn.Lock()
  95. defer dn.Unlock()
  96. for _, v := range deletedVolumes {
  97. disk := dn.getOrCreateDisk(v.DiskType)
  98. if _, found := disk.volumes[v.Id]; !found {
  99. continue
  100. }
  101. delete(disk.volumes, v.Id)
  102. deltaDiskUsages := newDiskUsages()
  103. deltaDiskUsage := deltaDiskUsages.getOrCreateDisk(types.ToDiskType(v.DiskType))
  104. deltaDiskUsage.volumeCount = -1
  105. if v.IsRemote() {
  106. deltaDiskUsage.remoteVolumeCount = -1
  107. }
  108. if !v.ReadOnly {
  109. deltaDiskUsage.activeVolumeCount = -1
  110. }
  111. disk.UpAdjustDiskUsageDelta(deltaDiskUsages)
  112. }
  113. for _, v := range newVolumes {
  114. dn.doAddOrUpdateVolume(v)
  115. }
  116. return
  117. }
  118. func (dn *DataNode) AdjustMaxVolumeCounts(maxVolumeCounts map[string]uint32) {
  119. deltaDiskUsages := newDiskUsages()
  120. for diskType, maxVolumeCount := range maxVolumeCounts {
  121. if maxVolumeCount == 0 {
  122. // the volume server may have set the max to zero
  123. continue
  124. }
  125. dt := types.ToDiskType(diskType)
  126. currentDiskUsage := dn.diskUsages.getOrCreateDisk(dt)
  127. if currentDiskUsage.maxVolumeCount == int64(maxVolumeCount) {
  128. continue
  129. }
  130. disk := dn.getOrCreateDisk(dt.String())
  131. deltaDiskUsage := deltaDiskUsages.getOrCreateDisk(dt)
  132. deltaDiskUsage.maxVolumeCount = int64(maxVolumeCount) - currentDiskUsage.maxVolumeCount
  133. disk.UpAdjustDiskUsageDelta(deltaDiskUsages)
  134. }
  135. }
  136. func (dn *DataNode) GetVolumes() (ret []storage.VolumeInfo) {
  137. dn.RLock()
  138. for _, c := range dn.children {
  139. disk := c.(*Disk)
  140. ret = append(ret, disk.GetVolumes()...)
  141. }
  142. dn.RUnlock()
  143. return ret
  144. }
  145. func (dn *DataNode) GetVolumesById(id needle.VolumeId) (vInfo storage.VolumeInfo, err error) {
  146. dn.RLock()
  147. defer dn.RUnlock()
  148. found := false
  149. for _, c := range dn.children {
  150. disk := c.(*Disk)
  151. vInfo, found = disk.volumes[id]
  152. if found {
  153. break
  154. }
  155. }
  156. if found {
  157. return vInfo, nil
  158. } else {
  159. return storage.VolumeInfo{}, fmt.Errorf("volumeInfo not found")
  160. }
  161. }
  162. func (dn *DataNode) GetDataCenter() *DataCenter {
  163. rack := dn.Parent()
  164. if rack == nil {
  165. return nil
  166. }
  167. dcNode := rack.Parent()
  168. if dcNode == nil {
  169. return nil
  170. }
  171. dcValue := dcNode.GetValue()
  172. return dcValue.(*DataCenter)
  173. }
  174. func (dn *DataNode) GetRack() *Rack {
  175. return dn.Parent().(*NodeImpl).value.(*Rack)
  176. }
  177. func (dn *DataNode) GetTopology() *Topology {
  178. p := dn.Parent()
  179. for p.Parent() != nil {
  180. p = p.Parent()
  181. }
  182. t := p.(*Topology)
  183. return t
  184. }
  185. func (dn *DataNode) MatchLocation(ip string, port int) bool {
  186. return dn.Ip == ip && dn.Port == port
  187. }
  188. func (dn *DataNode) Url() string {
  189. return util.JoinHostPort(dn.Ip, dn.Port)
  190. }
  191. func (dn *DataNode) ServerAddress() pb.ServerAddress {
  192. return pb.NewServerAddress(dn.Ip, dn.Port, dn.GrpcPort)
  193. }
  194. type DataNodeInfo struct {
  195. Url string `json:"Url"`
  196. PublicUrl string `json:"PublicUrl"`
  197. Volumes int64 `json:"Volumes"`
  198. EcShards int64 `json:"EcShards"`
  199. Max int64 `json:"Max"`
  200. VolumeIds string `json:"VolumeIds"`
  201. }
  202. func (dn *DataNode) ToInfo() (info DataNodeInfo) {
  203. info.Url = dn.Url()
  204. info.PublicUrl = dn.PublicUrl
  205. // aggregated volume info
  206. var volumeCount, ecShardCount, maxVolumeCount int64
  207. var volumeIds string
  208. for _, diskUsage := range dn.diskUsages.usages {
  209. volumeCount += diskUsage.volumeCount
  210. ecShardCount += diskUsage.ecShardCount
  211. maxVolumeCount += diskUsage.maxVolumeCount
  212. }
  213. for _, disk := range dn.Children() {
  214. d := disk.(*Disk)
  215. volumeIds += " " + d.GetVolumeIds()
  216. }
  217. info.Volumes = volumeCount
  218. info.EcShards = ecShardCount
  219. info.Max = maxVolumeCount
  220. info.VolumeIds = volumeIds
  221. return
  222. }
  223. func (dn *DataNode) ToDataNodeInfo() *master_pb.DataNodeInfo {
  224. m := &master_pb.DataNodeInfo{
  225. Id: string(dn.Id()),
  226. DiskInfos: make(map[string]*master_pb.DiskInfo),
  227. GrpcPort: uint32(dn.GrpcPort),
  228. }
  229. for _, c := range dn.Children() {
  230. disk := c.(*Disk)
  231. m.DiskInfos[string(disk.Id())] = disk.ToDiskInfo()
  232. }
  233. return m
  234. }
  235. // GetVolumeIds returns the human readable volume ids limited to count of max 100.
  236. func (dn *DataNode) GetVolumeIds() string {
  237. dn.RLock()
  238. defer dn.RUnlock()
  239. existingVolumes := dn.getVolumes()
  240. ids := make([]int, 0, len(existingVolumes))
  241. for k := range existingVolumes {
  242. ids = append(ids, int(k))
  243. }
  244. return util.HumanReadableIntsMax(100, ids...)
  245. }
  246. func (dn *DataNode) getVolumes() []storage.VolumeInfo {
  247. var existingVolumes []storage.VolumeInfo
  248. for _, c := range dn.children {
  249. disk := c.(*Disk)
  250. existingVolumes = append(existingVolumes, disk.GetVolumes()...)
  251. }
  252. return existingVolumes
  253. }