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.

368 lines
11 KiB

13 years ago
6 years ago
13 years ago
6 years ago
6 years ago
13 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
9 years ago
  1. package topology
  2. import (
  3. "errors"
  4. "github.com/chrislusf/seaweedfs/weed/storage"
  5. "math/rand"
  6. "strings"
  7. "sync"
  8. "sync/atomic"
  9. "github.com/chrislusf/seaweedfs/weed/glog"
  10. "github.com/chrislusf/seaweedfs/weed/storage/erasure_coding"
  11. "github.com/chrislusf/seaweedfs/weed/storage/needle"
  12. )
  13. type NodeId string
  14. type Node interface {
  15. Id() NodeId
  16. String() string
  17. FreeSpace() int64
  18. ReserveOneVolume(r int64) (*DataNode, error)
  19. UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta int64)
  20. UpAdjustMaxSsdVolumeCountDelta(maxSsdVolumeCountDelta int64)
  21. UpAdjustVolumeCountDelta(volumeCountDelta int64)
  22. UpAdjustSsdVolumeCountDelta(ssdVolumeCountDelta int64)
  23. UpAdjustRemoteVolumeCountDelta(remoteVolumeCountDelta int64)
  24. UpAdjustEcShardCountDelta(ecShardCountDelta int64)
  25. UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta int64)
  26. UpAdjustMaxVolumeId(vid needle.VolumeId)
  27. GetVolumeCount() int64
  28. GetSsdVolumeCount() int64
  29. GetEcShardCount() int64
  30. GetActiveVolumeCount() int64
  31. GetRemoteVolumeCount() int64
  32. GetMaxVolumeCount() int64
  33. GetMaxSsdVolumeCount() int64
  34. GetMaxVolumeId() needle.VolumeId
  35. SetParent(Node)
  36. LinkChildNode(node Node)
  37. UnlinkChildNode(nodeId NodeId)
  38. CollectDeadNodeAndFullVolumes(freshThreshHold int64, volumeSizeLimit uint64)
  39. IsDataNode() bool
  40. IsRack() bool
  41. IsDataCenter() bool
  42. Children() []Node
  43. Parent() Node
  44. GetValue() interface{} //get reference to the topology,dc,rack,datanode
  45. }
  46. type NodeImpl struct {
  47. volumeCount int64
  48. remoteVolumeCount int64
  49. ssdVolumeCount int64
  50. activeVolumeCount int64
  51. ecShardCount int64
  52. maxVolumeCount int64
  53. maxSsdVolumeCount int64
  54. id NodeId
  55. parent Node
  56. sync.RWMutex // lock children
  57. children map[NodeId]Node
  58. maxVolumeId needle.VolumeId
  59. //for rack, data center, topology
  60. nodeType string
  61. value interface{}
  62. }
  63. // the first node must satisfy filterFirstNodeFn(), the rest nodes must have one free slot
  64. func (n *NodeImpl) PickNodesByWeight(numberOfNodes int, filterFirstNodeFn func(dn Node) error) (firstNode Node, restNodes []Node, err error) {
  65. var totalWeights int64
  66. var errs []string
  67. n.RLock()
  68. candidates := make([]Node, 0, len(n.children))
  69. candidatesWeights := make([]int64, 0, len(n.children))
  70. //pick nodes which has enough free volumes as candidates, and use free volumes number as node weight.
  71. for _, node := range n.children {
  72. if node.FreeSpace() <= 0 {
  73. continue
  74. }
  75. totalWeights += node.FreeSpace()
  76. candidates = append(candidates, node)
  77. candidatesWeights = append(candidatesWeights, node.FreeSpace())
  78. }
  79. n.RUnlock()
  80. if len(candidates) < numberOfNodes {
  81. glog.V(0).Infoln(n.Id(), "failed to pick", numberOfNodes, "from ", len(candidates), "node candidates")
  82. return nil, nil, errors.New("No enough data node found!")
  83. }
  84. //pick nodes randomly by weights, the node picked earlier has higher final weights
  85. sortedCandidates := make([]Node, 0, len(candidates))
  86. for i := 0; i < len(candidates); i++ {
  87. weightsInterval := rand.Int63n(totalWeights)
  88. lastWeights := int64(0)
  89. for k, weights := range candidatesWeights {
  90. if (weightsInterval >= lastWeights) && (weightsInterval < lastWeights+weights) {
  91. sortedCandidates = append(sortedCandidates, candidates[k])
  92. candidatesWeights[k] = 0
  93. totalWeights -= weights
  94. break
  95. }
  96. lastWeights += weights
  97. }
  98. }
  99. restNodes = make([]Node, 0, numberOfNodes-1)
  100. ret := false
  101. n.RLock()
  102. for k, node := range sortedCandidates {
  103. if err := filterFirstNodeFn(node); err == nil {
  104. firstNode = node
  105. if k >= numberOfNodes-1 {
  106. restNodes = sortedCandidates[:numberOfNodes-1]
  107. } else {
  108. restNodes = append(restNodes, sortedCandidates[:k]...)
  109. restNodes = append(restNodes, sortedCandidates[k+1:numberOfNodes]...)
  110. }
  111. ret = true
  112. break
  113. } else {
  114. errs = append(errs, string(node.Id())+":"+err.Error())
  115. }
  116. }
  117. n.RUnlock()
  118. if !ret {
  119. return nil, nil, errors.New("No matching data node found! \n" + strings.Join(errs, "\n"))
  120. }
  121. return
  122. }
  123. func (n *NodeImpl) IsDataNode() bool {
  124. return n.nodeType == "DataNode"
  125. }
  126. func (n *NodeImpl) IsRack() bool {
  127. return n.nodeType == "Rack"
  128. }
  129. func (n *NodeImpl) IsDataCenter() bool {
  130. return n.nodeType == "DataCenter"
  131. }
  132. func (n *NodeImpl) String() string {
  133. if n.parent != nil {
  134. return n.parent.String() + ":" + string(n.id)
  135. }
  136. return string(n.id)
  137. }
  138. func (n *NodeImpl) Id() NodeId {
  139. return n.id
  140. }
  141. func (n *NodeImpl) AvailableSpaceFor(option *VolumeGrowOption) int64 {
  142. freeVolumeSlotCount := n.maxVolumeCount + n.remoteVolumeCount - n.volumeCount
  143. if option.DiskType == storage.SsdType {
  144. freeVolumeSlotCount = n.maxSsdVolumeCount - n.ssdVolumeCount
  145. }
  146. if n.ecShardCount > 0 {
  147. freeVolumeSlotCount = freeVolumeSlotCount - n.ecShardCount/erasure_coding.DataShardsCount - 1
  148. }
  149. return freeVolumeSlotCount
  150. }
  151. func (n *NodeImpl) FreeSpace() int64 {
  152. freeVolumeSlotCount := n.maxVolumeCount + n.maxSsdVolumeCount + n.remoteVolumeCount - n.volumeCount - n.ssdVolumeCount
  153. if n.ecShardCount > 0 {
  154. freeVolumeSlotCount = freeVolumeSlotCount - n.ecShardCount/erasure_coding.DataShardsCount - 1
  155. }
  156. return freeVolumeSlotCount
  157. }
  158. func (n *NodeImpl) SetParent(node Node) {
  159. n.parent = node
  160. }
  161. func (n *NodeImpl) Children() (ret []Node) {
  162. n.RLock()
  163. defer n.RUnlock()
  164. for _, c := range n.children {
  165. ret = append(ret, c)
  166. }
  167. return ret
  168. }
  169. func (n *NodeImpl) Parent() Node {
  170. return n.parent
  171. }
  172. func (n *NodeImpl) GetValue() interface{} {
  173. return n.value
  174. }
  175. func (n *NodeImpl) ReserveOneVolume(r int64) (assignedNode *DataNode, err error) {
  176. n.RLock()
  177. defer n.RUnlock()
  178. for _, node := range n.children {
  179. freeSpace := node.FreeSpace()
  180. // fmt.Println("r =", r, ", node =", node, ", freeSpace =", freeSpace)
  181. if freeSpace <= 0 {
  182. continue
  183. }
  184. if r >= freeSpace {
  185. r -= freeSpace
  186. } else {
  187. if node.IsDataNode() && node.FreeSpace() > 0 {
  188. // fmt.Println("vid =", vid, " assigned to node =", node, ", freeSpace =", node.FreeSpace())
  189. return node.(*DataNode), nil
  190. }
  191. assignedNode, err = node.ReserveOneVolume(r)
  192. if err == nil {
  193. return
  194. }
  195. }
  196. }
  197. return nil, errors.New("No free volume slot found!")
  198. }
  199. func (n *NodeImpl) UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta int64) { //can be negative
  200. if maxVolumeCountDelta == 0 {
  201. return
  202. }
  203. atomic.AddInt64(&n.maxVolumeCount, maxVolumeCountDelta)
  204. if n.parent != nil {
  205. n.parent.UpAdjustMaxVolumeCountDelta(maxVolumeCountDelta)
  206. }
  207. }
  208. func (n *NodeImpl) UpAdjustMaxSsdVolumeCountDelta(maxSsdVolumeCountDelta int64) { //can be negative
  209. if maxSsdVolumeCountDelta == 0 {
  210. return
  211. }
  212. atomic.AddInt64(&n.maxSsdVolumeCount, maxSsdVolumeCountDelta)
  213. if n.parent != nil {
  214. n.parent.UpAdjustMaxSsdVolumeCountDelta(maxSsdVolumeCountDelta)
  215. }
  216. }
  217. func (n *NodeImpl) UpAdjustVolumeCountDelta(volumeCountDelta int64) { //can be negative
  218. if volumeCountDelta == 0 {
  219. return
  220. }
  221. atomic.AddInt64(&n.volumeCount, volumeCountDelta)
  222. if n.parent != nil {
  223. n.parent.UpAdjustVolumeCountDelta(volumeCountDelta)
  224. }
  225. }
  226. func (n *NodeImpl) UpAdjustRemoteVolumeCountDelta(remoteVolumeCountDelta int64) { //can be negative
  227. if remoteVolumeCountDelta == 0 {
  228. return
  229. }
  230. atomic.AddInt64(&n.remoteVolumeCount, remoteVolumeCountDelta)
  231. if n.parent != nil {
  232. n.parent.UpAdjustRemoteVolumeCountDelta(remoteVolumeCountDelta)
  233. }
  234. }
  235. func (n *NodeImpl) UpAdjustSsdVolumeCountDelta(ssdVolumeCountDelta int64) { //can be negative
  236. if ssdVolumeCountDelta == 0 {
  237. return
  238. }
  239. atomic.AddInt64(&n.ssdVolumeCount, ssdVolumeCountDelta)
  240. if n.parent != nil {
  241. n.parent.UpAdjustSsdVolumeCountDelta(ssdVolumeCountDelta)
  242. }
  243. }
  244. func (n *NodeImpl) UpAdjustEcShardCountDelta(ecShardCountDelta int64) { //can be negative
  245. if ecShardCountDelta == 0 {
  246. return
  247. }
  248. atomic.AddInt64(&n.ecShardCount, ecShardCountDelta)
  249. if n.parent != nil {
  250. n.parent.UpAdjustEcShardCountDelta(ecShardCountDelta)
  251. }
  252. }
  253. func (n *NodeImpl) UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta int64) { //can be negative
  254. if activeVolumeCountDelta == 0 {
  255. return
  256. }
  257. atomic.AddInt64(&n.activeVolumeCount, activeVolumeCountDelta)
  258. if n.parent != nil {
  259. n.parent.UpAdjustActiveVolumeCountDelta(activeVolumeCountDelta)
  260. }
  261. }
  262. func (n *NodeImpl) UpAdjustMaxVolumeId(vid needle.VolumeId) { //can be negative
  263. if n.maxVolumeId < vid {
  264. n.maxVolumeId = vid
  265. if n.parent != nil {
  266. n.parent.UpAdjustMaxVolumeId(vid)
  267. }
  268. }
  269. }
  270. func (n *NodeImpl) GetMaxVolumeId() needle.VolumeId {
  271. return n.maxVolumeId
  272. }
  273. func (n *NodeImpl) GetVolumeCount() int64 {
  274. return n.volumeCount
  275. }
  276. func (n *NodeImpl) GetSsdVolumeCount() int64 {
  277. return n.ssdVolumeCount
  278. }
  279. func (n *NodeImpl) GetEcShardCount() int64 {
  280. return n.ecShardCount
  281. }
  282. func (n *NodeImpl) GetRemoteVolumeCount() int64 {
  283. return n.remoteVolumeCount
  284. }
  285. func (n *NodeImpl) GetActiveVolumeCount() int64 {
  286. return n.activeVolumeCount
  287. }
  288. func (n *NodeImpl) GetMaxVolumeCount() int64 {
  289. return n.maxVolumeCount
  290. }
  291. func (n *NodeImpl) GetMaxSsdVolumeCount() int64 {
  292. return n.maxSsdVolumeCount
  293. }
  294. func (n *NodeImpl) LinkChildNode(node Node) {
  295. n.Lock()
  296. defer n.Unlock()
  297. if n.children[node.Id()] == nil {
  298. n.children[node.Id()] = node
  299. n.UpAdjustMaxVolumeCountDelta(node.GetMaxVolumeCount())
  300. n.UpAdjustMaxSsdVolumeCountDelta(node.GetMaxSsdVolumeCount())
  301. n.UpAdjustMaxVolumeId(node.GetMaxVolumeId())
  302. n.UpAdjustVolumeCountDelta(node.GetVolumeCount())
  303. n.UpAdjustSsdVolumeCountDelta(node.GetSsdVolumeCount())
  304. n.UpAdjustRemoteVolumeCountDelta(node.GetRemoteVolumeCount())
  305. n.UpAdjustEcShardCountDelta(node.GetEcShardCount())
  306. n.UpAdjustActiveVolumeCountDelta(node.GetActiveVolumeCount())
  307. node.SetParent(n)
  308. glog.V(0).Infoln(n, "adds child", node.Id())
  309. }
  310. }
  311. func (n *NodeImpl) UnlinkChildNode(nodeId NodeId) {
  312. n.Lock()
  313. defer n.Unlock()
  314. node := n.children[nodeId]
  315. if node != nil {
  316. node.SetParent(nil)
  317. delete(n.children, node.Id())
  318. n.UpAdjustVolumeCountDelta(-node.GetVolumeCount())
  319. n.UpAdjustSsdVolumeCountDelta(-node.GetSsdVolumeCount())
  320. n.UpAdjustRemoteVolumeCountDelta(-node.GetRemoteVolumeCount())
  321. n.UpAdjustEcShardCountDelta(-node.GetEcShardCount())
  322. n.UpAdjustActiveVolumeCountDelta(-node.GetActiveVolumeCount())
  323. n.UpAdjustMaxVolumeCountDelta(-node.GetMaxVolumeCount())
  324. n.UpAdjustMaxSsdVolumeCountDelta(-node.GetMaxSsdVolumeCount())
  325. glog.V(0).Infoln(n, "removes", node.Id())
  326. }
  327. }
  328. func (n *NodeImpl) CollectDeadNodeAndFullVolumes(freshThreshHold int64, volumeSizeLimit uint64) {
  329. if n.IsRack() {
  330. for _, c := range n.Children() {
  331. dn := c.(*DataNode) //can not cast n to DataNode
  332. for _, v := range dn.GetVolumes() {
  333. if uint64(v.Size) >= volumeSizeLimit {
  334. //fmt.Println("volume",v.Id,"size",v.Size,">",volumeSizeLimit)
  335. n.GetTopology().chanFullVolumes <- v
  336. }
  337. }
  338. }
  339. } else {
  340. for _, c := range n.Children() {
  341. c.CollectDeadNodeAndFullVolumes(freshThreshHold, volumeSizeLimit)
  342. }
  343. }
  344. }
  345. func (n *NodeImpl) GetTopology() *Topology {
  346. var p Node
  347. p = n
  348. for p.Parent() != nil {
  349. p = p.Parent()
  350. }
  351. return p.GetValue().(*Topology)
  352. }