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.

101 lines
3.8 KiB

1 year ago
1 year ago
10 months ago
10 months ago
10 months ago
1 year ago
1 year ago
9 months ago
1 year ago
9 months ago
1 year ago
  1. package broker
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/seaweedfs/seaweedfs/weed/glog"
  6. "github.com/seaweedfs/seaweedfs/weed/mq/logstore"
  7. "github.com/seaweedfs/seaweedfs/weed/mq/pub_balancer"
  8. "github.com/seaweedfs/seaweedfs/weed/mq/topic"
  9. "github.com/seaweedfs/seaweedfs/weed/pb"
  10. "github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
  11. "github.com/seaweedfs/seaweedfs/weed/pb/schema_pb"
  12. "sync"
  13. )
  14. // AssignTopicPartitions Runs on the assigned broker, to execute the topic partition assignment
  15. func (b *MessageQueueBroker) AssignTopicPartitions(c context.Context, request *mq_pb.AssignTopicPartitionsRequest) (*mq_pb.AssignTopicPartitionsResponse, error) {
  16. ret := &mq_pb.AssignTopicPartitionsResponse{}
  17. // drain existing topic partition subscriptions
  18. for _, assignment := range request.BrokerPartitionAssignments {
  19. t := topic.FromPbTopic(request.Topic)
  20. partition := topic.FromPbPartition(assignment.Partition)
  21. b.accessLock.Lock()
  22. if request.IsDraining {
  23. // TODO drain existing topic partition subscriptions
  24. b.localTopicManager.RemoveLocalPartition(t, partition)
  25. } else {
  26. var localPartition *topic.LocalPartition
  27. if localPartition = b.localTopicManager.GetLocalPartition(t, partition); localPartition == nil {
  28. localPartition = topic.NewLocalPartition(partition, b.genLogFlushFunc(t, partition), logstore.GenMergedReadFunc(b, t, partition))
  29. b.localTopicManager.AddLocalPartition(t, localPartition)
  30. }
  31. }
  32. b.accessLock.Unlock()
  33. }
  34. // if is leader, notify the followers to drain existing topic partition subscriptions
  35. if request.IsLeader {
  36. for _, brokerPartition := range request.BrokerPartitionAssignments {
  37. if follower := brokerPartition.FollowerBroker; follower != "" {
  38. err := pb.WithBrokerGrpcClient(false, follower, b.grpcDialOption, func(client mq_pb.SeaweedMessagingClient) error {
  39. _, err := client.AssignTopicPartitions(context.Background(), request)
  40. return err
  41. })
  42. if err != nil {
  43. return ret, err
  44. }
  45. }
  46. }
  47. }
  48. glog.V(0).Infof("AssignTopicPartitions: topic %s partition assignments: %v", request.Topic, request.BrokerPartitionAssignments)
  49. return ret, nil
  50. }
  51. // called by broker leader to drain existing partitions.
  52. // new/updated partitions will be detected by broker from the filer
  53. func (b *MessageQueueBroker) assignTopicPartitionsToBrokers(ctx context.Context, t *schema_pb.Topic, assignments []*mq_pb.BrokerPartitionAssignment, isAdd bool) error {
  54. // notify the brokers to create the topic partitions in parallel
  55. var wg sync.WaitGroup
  56. for _, bpa := range assignments {
  57. wg.Add(1)
  58. go func(bpa *mq_pb.BrokerPartitionAssignment) {
  59. defer wg.Done()
  60. if doCreateErr := b.withBrokerClient(false, pb.ServerAddress(bpa.LeaderBroker), func(client mq_pb.SeaweedMessagingClient) error {
  61. _, doCreateErr := client.AssignTopicPartitions(ctx, &mq_pb.AssignTopicPartitionsRequest{
  62. Topic: t,
  63. BrokerPartitionAssignments: []*mq_pb.BrokerPartitionAssignment{
  64. {
  65. Partition: bpa.Partition,
  66. },
  67. },
  68. IsLeader: true,
  69. IsDraining: !isAdd,
  70. })
  71. if doCreateErr != nil {
  72. if !isAdd {
  73. return fmt.Errorf("drain topic %s %v on %s: %v", t, bpa.LeaderBroker, bpa.Partition, doCreateErr)
  74. } else {
  75. return fmt.Errorf("create topic %s %v on %s: %v", t, bpa.LeaderBroker, bpa.Partition, doCreateErr)
  76. }
  77. }
  78. brokerStats, found := b.PubBalancer.Brokers.Get(bpa.LeaderBroker)
  79. if !found {
  80. brokerStats = pub_balancer.NewBrokerStats()
  81. if !b.PubBalancer.Brokers.SetIfAbsent(bpa.LeaderBroker, brokerStats) {
  82. brokerStats, _ = b.PubBalancer.Brokers.Get(bpa.LeaderBroker)
  83. }
  84. }
  85. brokerStats.RegisterAssignment(t, bpa.Partition, isAdd)
  86. return nil
  87. }); doCreateErr != nil {
  88. glog.Errorf("create topic %s partition %+v on %s: %v", t, bpa.Partition, bpa.LeaderBroker, doCreateErr)
  89. }
  90. }(bpa)
  91. }
  92. wg.Wait()
  93. return nil
  94. }