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.

180 lines
5.7 KiB

7 years ago
  1. package weed_server
  2. import (
  3. "fmt"
  4. "net"
  5. "time"
  6. "github.com/chrislusf/seaweedfs/weed/security"
  7. "github.com/chrislusf/seaweedfs/weed/storage/erasure_coding"
  8. "github.com/spf13/viper"
  9. "google.golang.org/grpc"
  10. "github.com/chrislusf/seaweedfs/weed/glog"
  11. "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
  12. "github.com/chrislusf/seaweedfs/weed/util"
  13. "golang.org/x/net/context"
  14. )
  15. func (vs *VolumeServer) GetMaster() string {
  16. return vs.currentMaster
  17. }
  18. func (vs *VolumeServer) heartbeat() {
  19. glog.V(0).Infof("Volume server start with masters: %v", vs.MasterNodes)
  20. vs.store.SetDataCenter(vs.dataCenter)
  21. vs.store.SetRack(vs.rack)
  22. grpcDialOption := security.LoadClientTLS(viper.Sub("grpc"), "volume")
  23. var err error
  24. var newLeader string
  25. for {
  26. for _, master := range vs.MasterNodes {
  27. if newLeader != "" {
  28. master = newLeader
  29. }
  30. masterGrpcAddress, parseErr := util.ParseServerToGrpcAddress(master)
  31. if parseErr != nil {
  32. glog.V(0).Infof("failed to parse master grpc %v: %v", masterGrpcAddress, parseErr)
  33. continue
  34. }
  35. newLeader, err = vs.doHeartbeat(context.Background(), master, masterGrpcAddress, grpcDialOption, time.Duration(vs.pulseSeconds)*time.Second)
  36. if err != nil {
  37. glog.V(0).Infof("heartbeat error: %v", err)
  38. time.Sleep(time.Duration(vs.pulseSeconds) * time.Second)
  39. newLeader = ""
  40. }
  41. }
  42. }
  43. }
  44. func (vs *VolumeServer) doHeartbeat(ctx context.Context, masterNode, masterGrpcAddress string, grpcDialOption grpc.DialOption, sleepInterval time.Duration) (newLeader string, err error) {
  45. grpcConection, err := util.GrpcDial(ctx, masterGrpcAddress, grpcDialOption)
  46. if err != nil {
  47. return "", fmt.Errorf("fail to dial %s : %v", masterNode, err)
  48. }
  49. defer grpcConection.Close()
  50. client := master_pb.NewSeaweedClient(grpcConection)
  51. stream, err := client.SendHeartbeat(ctx)
  52. if err != nil {
  53. glog.V(0).Infof("SendHeartbeat to %s: %v", masterNode, err)
  54. return "", err
  55. }
  56. glog.V(0).Infof("Heartbeat to: %v", masterNode)
  57. vs.currentMaster = masterNode
  58. doneChan := make(chan error, 1)
  59. go func() {
  60. for {
  61. in, err := stream.Recv()
  62. if err != nil {
  63. doneChan <- err
  64. return
  65. }
  66. if in.GetVolumeSizeLimit() != 0 {
  67. vs.store.SetVolumeSizeLimit(in.GetVolumeSizeLimit())
  68. }
  69. if in.GetLeader() != "" && masterNode != in.GetLeader() && !isSameIP(in.GetLeader(), masterNode) {
  70. glog.V(0).Infof("Volume Server found a new master newLeader: %v instead of %v", in.GetLeader(), masterNode)
  71. newLeader = in.GetLeader()
  72. doneChan <- nil
  73. return
  74. }
  75. }
  76. }()
  77. if err = stream.Send(vs.store.CollectHeartbeat()); err != nil {
  78. glog.V(0).Infof("Volume Server Failed to talk with master %s: %v", masterNode, err)
  79. return "", err
  80. }
  81. if err = stream.Send(vs.store.CollectErasureCodingHeartbeat()); err != nil {
  82. glog.V(0).Infof("Volume Server Failed to talk with master %s: %v", masterNode, err)
  83. return "", err
  84. }
  85. volumeTickChan := time.Tick(sleepInterval)
  86. ecShardTickChan := time.Tick(17 * sleepInterval)
  87. for {
  88. select {
  89. case volumeMessage := <-vs.store.NewVolumesChan:
  90. deltaBeat := &master_pb.Heartbeat{
  91. NewVolumes: []*master_pb.VolumeShortInformationMessage{
  92. &volumeMessage,
  93. },
  94. }
  95. glog.V(1).Infof("volume server %s:%d adds volume %d", vs.store.Ip, vs.store.Port, volumeMessage.Id)
  96. if err = stream.Send(deltaBeat); err != nil {
  97. glog.V(0).Infof("Volume Server Failed to update to master %s: %v", masterNode, err)
  98. return "", err
  99. }
  100. case ecShardMessage := <-vs.store.NewEcShardsChan:
  101. deltaBeat := &master_pb.Heartbeat{
  102. NewEcShards: []*master_pb.VolumeEcShardInformationMessage{
  103. &ecShardMessage,
  104. },
  105. }
  106. glog.V(1).Infof("volume server %s:%d adds ec shard %d:%d", vs.store.Ip, vs.store.Port, ecShardMessage.Id,
  107. erasure_coding.ShardBits(ecShardMessage.EcIndexBits).ShardIds())
  108. if err = stream.Send(deltaBeat); err != nil {
  109. glog.V(0).Infof("Volume Server Failed to update to master %s: %v", masterNode, err)
  110. return "", err
  111. }
  112. case volumeMessage := <-vs.store.DeletedVolumesChan:
  113. deltaBeat := &master_pb.Heartbeat{
  114. DeletedVolumes: []*master_pb.VolumeShortInformationMessage{
  115. &volumeMessage,
  116. },
  117. }
  118. glog.V(1).Infof("volume server %s:%d deletes volume %d", vs.store.Ip, vs.store.Port, volumeMessage.Id)
  119. if err = stream.Send(deltaBeat); err != nil {
  120. glog.V(0).Infof("Volume Server Failed to update to master %s: %v", masterNode, err)
  121. return "", err
  122. }
  123. case ecShardMessage := <-vs.store.DeletedEcShardsChan:
  124. deltaBeat := &master_pb.Heartbeat{
  125. DeletedEcShards: []*master_pb.VolumeEcShardInformationMessage{
  126. &ecShardMessage,
  127. },
  128. }
  129. glog.V(1).Infof("volume server %s:%d deletes ec shard %d:%d", vs.store.Ip, vs.store.Port, ecShardMessage.Id,
  130. erasure_coding.ShardBits(ecShardMessage.EcIndexBits).ShardIds())
  131. if err = stream.Send(deltaBeat); err != nil {
  132. glog.V(0).Infof("Volume Server Failed to update to master %s: %v", masterNode, err)
  133. return "", err
  134. }
  135. case <-volumeTickChan:
  136. glog.V(4).Infof("volume server %s:%d heartbeat", vs.store.Ip, vs.store.Port)
  137. if err = stream.Send(vs.store.CollectHeartbeat()); err != nil {
  138. glog.V(0).Infof("Volume Server Failed to talk with master %s: %v", masterNode, err)
  139. return "", err
  140. }
  141. case <-ecShardTickChan:
  142. glog.V(4).Infof("volume server %s:%d ec heartbeat", vs.store.Ip, vs.store.Port)
  143. if err = stream.Send(vs.store.CollectErasureCodingHeartbeat()); err != nil {
  144. glog.V(0).Infof("Volume Server Failed to talk with master %s: %v", masterNode, err)
  145. return "", err
  146. }
  147. case err = <-doneChan:
  148. return
  149. }
  150. }
  151. }
  152. func isSameIP(ip string, host string) bool {
  153. ips, err := net.LookupIP(host)
  154. if err != nil {
  155. return false
  156. }
  157. for _, t := range ips {
  158. if ip == t.String() {
  159. return true
  160. }
  161. }
  162. return false
  163. }