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.

226 lines
5.4 KiB

6 years ago
6 years ago
9 years ago
9 years ago
6 years ago
9 years ago
9 years ago
  1. package topology
  2. import (
  3. "fmt"
  4. "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
  5. "github.com/chrislusf/seaweedfs/weed/storage/needle"
  6. "github.com/chrislusf/seaweedfs/weed/storage/types"
  7. "github.com/chrislusf/seaweedfs/weed/util"
  8. "strconv"
  9. "github.com/chrislusf/seaweedfs/weed/glog"
  10. "github.com/chrislusf/seaweedfs/weed/storage"
  11. )
  12. type DataNode struct {
  13. NodeImpl
  14. Ip string
  15. Port int
  16. PublicUrl string
  17. LastSeen int64 // unix time in seconds
  18. }
  19. func NewDataNode(id string) *DataNode {
  20. dn := &DataNode{}
  21. dn.id = NodeId(id)
  22. dn.nodeType = "DataNode"
  23. dn.diskUsages = newDiskUsages()
  24. dn.children = make(map[NodeId]Node)
  25. dn.NodeImpl.value = dn
  26. return dn
  27. }
  28. func (dn *DataNode) String() string {
  29. dn.RLock()
  30. defer dn.RUnlock()
  31. return fmt.Sprintf("Node:%s, Ip:%s, Port:%d, PublicUrl:%s", dn.NodeImpl.String(), dn.Ip, dn.Port, dn.PublicUrl)
  32. }
  33. func (dn *DataNode) AddOrUpdateVolume(v storage.VolumeInfo) (isNew, isChangedRO bool) {
  34. dn.Lock()
  35. defer dn.Unlock()
  36. return dn.doAddOrUpdateVolume(v)
  37. }
  38. func (dn *DataNode) getOrCreateDisk(diskType string) *Disk {
  39. c, found := dn.children[NodeId(diskType)]
  40. if !found {
  41. c = NewDisk(diskType)
  42. dn.LinkChildNode(c)
  43. }
  44. disk := c.(*Disk)
  45. return disk
  46. }
  47. func (dn *DataNode) doAddOrUpdateVolume(v storage.VolumeInfo) (isNew, isChangedRO bool) {
  48. disk := dn.getOrCreateDisk(v.DiskType)
  49. return disk.AddOrUpdateVolume(v)
  50. }
  51. // UpdateVolumes detects new/deleted/changed volumes on a volume server
  52. // used in master to notify master clients of these changes.
  53. func (dn *DataNode) UpdateVolumes(actualVolumes []storage.VolumeInfo) (newVolumes, deletedVolumes, changeRO []storage.VolumeInfo) {
  54. actualVolumeMap := make(map[needle.VolumeId]storage.VolumeInfo)
  55. for _, v := range actualVolumes {
  56. actualVolumeMap[v.Id] = v
  57. }
  58. dn.Lock()
  59. defer dn.Unlock()
  60. existingVolumes := dn.getVolumes()
  61. for _, v := range existingVolumes {
  62. vid := v.Id
  63. if _, ok := actualVolumeMap[vid]; !ok {
  64. glog.V(0).Infoln("Deleting volume id:", vid)
  65. disk := dn.getOrCreateDisk(v.DiskType)
  66. delete(disk.volumes, vid)
  67. deletedVolumes = append(deletedVolumes, v)
  68. deltaDiskUsages := newDiskUsages()
  69. deltaDiskUsage := deltaDiskUsages.getOrCreateDisk(types.DiskType(v.DiskType))
  70. deltaDiskUsage.volumeCount = -1
  71. if v.IsRemote() {
  72. deltaDiskUsage.remoteVolumeCount = -1
  73. }
  74. if !v.ReadOnly {
  75. deltaDiskUsage.activeVolumeCount = -1
  76. }
  77. disk.UpAdjustDiskUsageDelta(deltaDiskUsages)
  78. }
  79. }
  80. for _, v := range actualVolumes {
  81. isNew, isChangedRO := dn.doAddOrUpdateVolume(v)
  82. if isNew {
  83. newVolumes = append(newVolumes, v)
  84. }
  85. if isChangedRO {
  86. changeRO = append(changeRO, v)
  87. }
  88. }
  89. return
  90. }
  91. func (dn *DataNode) DeltaUpdateVolumes(newVolumes, deletedVolumes []storage.VolumeInfo) {
  92. dn.Lock()
  93. defer dn.Unlock()
  94. for _, v := range deletedVolumes {
  95. disk := dn.getOrCreateDisk(v.DiskType)
  96. delete(disk.volumes, v.Id)
  97. deltaDiskUsages := newDiskUsages()
  98. deltaDiskUsage := deltaDiskUsages.getOrCreateDisk(types.DiskType(v.DiskType))
  99. deltaDiskUsage.volumeCount = -1
  100. if v.IsRemote() {
  101. deltaDiskUsage.remoteVolumeCount = -1
  102. }
  103. if !v.ReadOnly {
  104. deltaDiskUsage.activeVolumeCount = -1
  105. }
  106. disk.UpAdjustDiskUsageDelta(deltaDiskUsages)
  107. }
  108. for _, v := range newVolumes {
  109. dn.doAddOrUpdateVolume(v)
  110. }
  111. return
  112. }
  113. func (dn *DataNode) GetVolumes() (ret []storage.VolumeInfo) {
  114. dn.RLock()
  115. for _, c := range dn.children {
  116. disk := c.(*Disk)
  117. ret = append(ret, disk.GetVolumes()...)
  118. }
  119. dn.RUnlock()
  120. return ret
  121. }
  122. func (dn *DataNode) GetVolumesById(id needle.VolumeId) (vInfo storage.VolumeInfo, err error) {
  123. dn.RLock()
  124. defer dn.RUnlock()
  125. found := false
  126. for _, c := range dn.children {
  127. disk := c.(*Disk)
  128. vInfo, found = disk.volumes[id]
  129. if found {
  130. break
  131. }
  132. }
  133. if found {
  134. return vInfo, nil
  135. } else {
  136. return storage.VolumeInfo{}, fmt.Errorf("volumeInfo not found")
  137. }
  138. }
  139. func (dn *DataNode) GetDataCenter() *DataCenter {
  140. rack := dn.Parent()
  141. dcNode := rack.Parent()
  142. dcValue := dcNode.GetValue()
  143. return dcValue.(*DataCenter)
  144. }
  145. func (dn *DataNode) GetRack() *Rack {
  146. return dn.Parent().(*NodeImpl).value.(*Rack)
  147. }
  148. func (dn *DataNode) GetTopology() *Topology {
  149. p := dn.Parent()
  150. for p.Parent() != nil {
  151. p = p.Parent()
  152. }
  153. t := p.(*Topology)
  154. return t
  155. }
  156. func (dn *DataNode) MatchLocation(ip string, port int) bool {
  157. return dn.Ip == ip && dn.Port == port
  158. }
  159. func (dn *DataNode) Url() string {
  160. return dn.Ip + ":" + strconv.Itoa(dn.Port)
  161. }
  162. func (dn *DataNode) ToMap() interface{} {
  163. ret := make(map[string]interface{})
  164. ret["Url"] = dn.Url()
  165. ret["PublicUrl"] = dn.PublicUrl
  166. ret["Disks"] = dn.diskUsages.ToMap()
  167. return ret
  168. }
  169. func (dn *DataNode) ToDataNodeInfo() *master_pb.DataNodeInfo {
  170. m := &master_pb.DataNodeInfo{
  171. Id: string(dn.Id()),
  172. }
  173. for _, c := range dn.Children() {
  174. disk := c.(*Disk)
  175. m.DiskInfos[string(disk.Id())] = disk.ToDiskInfo()
  176. }
  177. return m
  178. }
  179. // GetVolumeIds returns the human readable volume ids limited to count of max 100.
  180. func (dn *DataNode) GetVolumeIds() string {
  181. dn.RLock()
  182. defer dn.RUnlock()
  183. existingVolumes := dn.getVolumes()
  184. ids := make([]int, 0, len(existingVolumes))
  185. for k := range existingVolumes {
  186. ids = append(ids, int(k))
  187. }
  188. return util.HumanReadableIntsMax(100, ids...)
  189. }
  190. func (dn *DataNode) getVolumes() []storage.VolumeInfo {
  191. var existingVolumes []storage.VolumeInfo
  192. for _, c := range dn.children {
  193. disk := c.(*Disk)
  194. existingVolumes = append(existingVolumes, disk.GetVolumes()...)
  195. }
  196. return existingVolumes
  197. }