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.

205 lines
5.5 KiB

Merge accumulated changes related to message queue (#5098) * balance partitions on brokers * prepare topic partition first and then publish, move partition * purge unused APIs * clean up * adjust logs * add BalanceTopics() grpc API * configure topic * configure topic command * refactor * repair missing partitions * sequence of operations to ensure ordering * proto to close publishers and consumers * rename file * topic partition versioned by unixTimeNs * create local topic partition * close publishers * randomize the client name * wait until no publishers * logs * close stop publisher channel * send last ack * comments * comment * comments * support list of brokers * add cli options * Update .gitignore * logs * return io.eof directly * refactor * optionally create topic * refactoring * detect consumer disconnection * sub client wait for more messages * subscribe by time stamp * rename * rename to sub_balancer * rename * adjust comments * rename * fix compilation * rename * rename * SubscriberToSubCoordinator * sticky rebalance * go fmt * add tests * balance partitions on brokers * prepare topic partition first and then publish, move partition * purge unused APIs * clean up * adjust logs * add BalanceTopics() grpc API * configure topic * configure topic command * refactor * repair missing partitions * sequence of operations to ensure ordering * proto to close publishers and consumers * rename file * topic partition versioned by unixTimeNs * create local topic partition * close publishers * randomize the client name * wait until no publishers * logs * close stop publisher channel * send last ack * comments * comment * comments * support list of brokers * add cli options * Update .gitignore * logs * return io.eof directly * refactor * optionally create topic * refactoring * detect consumer disconnection * sub client wait for more messages * subscribe by time stamp * rename * rename to sub_balancer * rename * adjust comments * rename * fix compilation * rename * rename * SubscriberToSubCoordinator * sticky rebalance * go fmt * add tests * tracking topic=>broker * merge * comment
1 year ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
12 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
6 months ago
12 months ago
11 months ago
12 months ago
6 months ago
12 months ago
11 months ago
12 months ago
6 months ago
12 months ago
11 months ago
12 months ago
6 months ago
12 months ago
11 months ago
6 months ago
11 months ago
11 months ago
6 months ago
12 months ago
  1. package pub_balancer
  2. import (
  3. "fmt"
  4. cmap "github.com/orcaman/concurrent-map/v2"
  5. "github.com/seaweedfs/seaweedfs/weed/pb/mq_pb"
  6. "github.com/seaweedfs/seaweedfs/weed/pb/schema_pb"
  7. "github.com/stretchr/testify/assert"
  8. "testing"
  9. )
  10. func Test_allocateOneBroker(t *testing.T) {
  11. brokers := cmap.New[*BrokerStats]()
  12. brokers.SetIfAbsent("localhost:17777", &BrokerStats{
  13. TopicPartitionCount: 0,
  14. CpuUsagePercent: 0,
  15. })
  16. tests := []struct {
  17. name string
  18. args args
  19. wantAssignments []*mq_pb.BrokerPartitionAssignment
  20. }{
  21. {
  22. name: "test only one broker",
  23. args: args{
  24. brokers: brokers,
  25. partitionCount: 1,
  26. },
  27. wantAssignments: []*mq_pb.BrokerPartitionAssignment{
  28. {
  29. LeaderBroker: "localhost:17777",
  30. Partition: &schema_pb.Partition{
  31. RingSize: MaxPartitionCount,
  32. RangeStart: 0,
  33. RangeStop: MaxPartitionCount,
  34. },
  35. },
  36. },
  37. },
  38. }
  39. testThem(t, tests)
  40. }
  41. type args struct {
  42. brokers cmap.ConcurrentMap[string, *BrokerStats]
  43. partitionCount int32
  44. }
  45. func testThem(t *testing.T, tests []struct {
  46. name string
  47. args args
  48. wantAssignments []*mq_pb.BrokerPartitionAssignment
  49. }) {
  50. for _, tt := range tests {
  51. t.Run(tt.name, func(t *testing.T) {
  52. gotAssignments := AllocateTopicPartitions(tt.args.brokers, tt.args.partitionCount)
  53. assert.Equal(t, len(tt.wantAssignments), len(gotAssignments))
  54. for i, gotAssignment := range gotAssignments {
  55. assert.Equal(t, tt.wantAssignments[i].LeaderBroker, gotAssignment.LeaderBroker)
  56. assert.Equal(t, tt.wantAssignments[i].Partition.RangeStart, gotAssignment.Partition.RangeStart)
  57. assert.Equal(t, tt.wantAssignments[i].Partition.RangeStop, gotAssignment.Partition.RangeStop)
  58. assert.Equal(t, tt.wantAssignments[i].Partition.RingSize, gotAssignment.Partition.RingSize)
  59. }
  60. })
  61. }
  62. }
  63. func TestEnsureAssignmentsToActiveBrokersX(t *testing.T) {
  64. type args struct {
  65. activeBrokers cmap.ConcurrentMap[string, *BrokerStats]
  66. followerCount int
  67. assignments []*mq_pb.BrokerPartitionAssignment
  68. }
  69. activeBrokers := cmap.New[*BrokerStats]()
  70. activeBrokers.SetIfAbsent("localhost:1", &BrokerStats{})
  71. activeBrokers.SetIfAbsent("localhost:2", &BrokerStats{})
  72. activeBrokers.SetIfAbsent("localhost:3", &BrokerStats{})
  73. activeBrokers.SetIfAbsent("localhost:4", &BrokerStats{})
  74. activeBrokers.SetIfAbsent("localhost:5", &BrokerStats{})
  75. activeBrokers.SetIfAbsent("localhost:6", &BrokerStats{})
  76. lowActiveBrokers := cmap.New[*BrokerStats]()
  77. lowActiveBrokers.SetIfAbsent("localhost:1", &BrokerStats{})
  78. lowActiveBrokers.SetIfAbsent("localhost:2", &BrokerStats{})
  79. singleActiveBroker := cmap.New[*BrokerStats]()
  80. singleActiveBroker.SetIfAbsent("localhost:1", &BrokerStats{})
  81. tests := []struct {
  82. name string
  83. args args
  84. hasChanges bool
  85. }{
  86. {
  87. name: "test empty leader",
  88. args: args{
  89. activeBrokers: activeBrokers,
  90. followerCount: 1,
  91. assignments: []*mq_pb.BrokerPartitionAssignment{
  92. {
  93. LeaderBroker: "",
  94. Partition: &schema_pb.Partition{},
  95. FollowerBroker: "localhost:2",
  96. },
  97. },
  98. },
  99. hasChanges: true,
  100. },
  101. {
  102. name: "test empty follower",
  103. args: args{
  104. activeBrokers: activeBrokers,
  105. followerCount: 1,
  106. assignments: []*mq_pb.BrokerPartitionAssignment{
  107. {
  108. LeaderBroker: "localhost:1",
  109. Partition: &schema_pb.Partition{},
  110. FollowerBroker: "",
  111. },
  112. },
  113. },
  114. hasChanges: true,
  115. },
  116. {
  117. name: "test dead follower",
  118. args: args{
  119. activeBrokers: activeBrokers,
  120. followerCount: 1,
  121. assignments: []*mq_pb.BrokerPartitionAssignment{
  122. {
  123. LeaderBroker: "localhost:1",
  124. Partition: &schema_pb.Partition{},
  125. FollowerBroker: "localhost:200",
  126. },
  127. },
  128. },
  129. hasChanges: true,
  130. },
  131. {
  132. name: "test dead leader and follower",
  133. args: args{
  134. activeBrokers: activeBrokers,
  135. followerCount: 1,
  136. assignments: []*mq_pb.BrokerPartitionAssignment{
  137. {
  138. LeaderBroker: "localhost:100",
  139. Partition: &schema_pb.Partition{},
  140. FollowerBroker: "localhost:200",
  141. },
  142. },
  143. },
  144. hasChanges: true,
  145. },
  146. {
  147. name: "test low active brokers",
  148. args: args{
  149. activeBrokers: lowActiveBrokers,
  150. followerCount: 3,
  151. assignments: []*mq_pb.BrokerPartitionAssignment{
  152. {
  153. LeaderBroker: "localhost:1",
  154. Partition: &schema_pb.Partition{},
  155. FollowerBroker: "localhost:2",
  156. },
  157. },
  158. },
  159. hasChanges: false,
  160. },
  161. {
  162. name: "test low active brokers with one follower",
  163. args: args{
  164. activeBrokers: lowActiveBrokers,
  165. followerCount: 1,
  166. assignments: []*mq_pb.BrokerPartitionAssignment{
  167. {
  168. LeaderBroker: "localhost:1",
  169. Partition: &schema_pb.Partition{},
  170. },
  171. },
  172. },
  173. hasChanges: true,
  174. },
  175. {
  176. name: "test single active broker",
  177. args: args{
  178. activeBrokers: singleActiveBroker,
  179. followerCount: 3,
  180. assignments: []*mq_pb.BrokerPartitionAssignment{
  181. {
  182. LeaderBroker: "localhost:1",
  183. Partition: &schema_pb.Partition{},
  184. FollowerBroker: "localhost:2",
  185. },
  186. },
  187. },
  188. hasChanges: true,
  189. },
  190. }
  191. for _, tt := range tests {
  192. t.Run(tt.name, func(t *testing.T) {
  193. fmt.Printf("%v before %v\n", tt.name, tt.args.assignments)
  194. hasChanges := EnsureAssignmentsToActiveBrokers(tt.args.activeBrokers, tt.args.followerCount, tt.args.assignments)
  195. assert.Equalf(t, tt.hasChanges, hasChanges, "EnsureAssignmentsToActiveBrokers(%v, %v, %v)", tt.args.activeBrokers, tt.args.followerCount, tt.args.assignments)
  196. fmt.Printf("%v after %v\n", tt.name, tt.args.assignments)
  197. })
  198. }
  199. }