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.

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