Amarendraレディ:
私は、生産者と消費者の枠組みを持っています。各プロデューサーがキューからキューと消費者の消費にプッシュします。任意の時点で、各消費者は単一のキューから消費すると、1つ以上のキューが存在することができます。しかし、プロデューサーはどのキューに生成することができます。消費者が遅い場合は、そのメッセージを重ね続けています。私は、すべてのコンシューマ・キューにかかわらず、消費者の速度にほぼ同じメッセージを持っているように、私はバランスの消費者をロードすることができますフレームワークが付属していますしようとしています。
例:
ここでQ1-Q3にかかわらずC1-C3消費者の速度のほぼ同じメッセージを有するようになっているキュー。今私が使っているデフォルトポリシーは、生産者のためのラウンドロビンですが、どの消費者が遅い場合には、キューにメッセージを追加し続けます。それはキューのいずれかに行くように、すべてのメッセージは同じ種類のものです。
で開始する任意の提案は有用です。
Amarendraレディ:
以下は、私が実施している私の解決策です。アルゴリズムは以下の通りである使用しました。
- 30秒ごとに、すべてのキューの平均見つけます。
- 消費者の遅れが特定の閾値よりも大きいに意味WRT場合は、そのキュー/消費者を無視します。
プロデューサーコード:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
public class Producer implements Runnable{
private List<BlockingQueue<Integer>> blockingQueues = new ArrayList<>();
private List<Integer> fullPartitions;
private List<Integer> activePartitions;
long timer = System.currentTimeMillis();
int THRESHOLD = 10000;
int currentQueue = 0;
public Producer(List<BlockingQueue<Integer>> blockingQueues, List<Integer> fullPartitions, List<Integer> activePartitions) {
this.blockingQueues = blockingQueues;
this.fullPartitions = fullPartitions;
this.activePartitions = activePartitions;
}
@Override
public void run() {
long start = System.currentTimeMillis();
while(true) {
blockingQueues.get(getNextID()).offer(new Random().nextInt(100000));
try {
if(System.currentTimeMillis()-start<300000)
Thread.sleep(1);
else
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private int getNextID() {
if(System.currentTimeMillis()-timer>30000) {
activePartitions = new ArrayList<>();
long mean = 0l;
for(int i=0;i<fullPartitions.size();i++)
mean += blockingQueues.get(i).size();
mean = mean/blockingQueues.size();
for(int i=0;i<fullPartitions.size();i++)
if(blockingQueues.get(i).size()-mean<THRESHOLD)
activePartitions.add(i);
timer = System.currentTimeMillis();
}
int partitionID = activePartitions.get(currentQueue%activePartitions.size());
currentQueue++;
return partitionID;
}
}
消費者:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Consumer implements Runnable{
private BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(100000000);
private int delayFactor;
public Consumer(BlockingQueue<Integer> blockingQueue, int delayFactor, int consumerNo) {
this.blockingQueue = blockingQueue;
this.delayFactor = delayFactor;
}
@Override
public void run() {
long start = System.currentTimeMillis();
while(true) {
try {
blockingQueue.take();
if(blockingQueue.isEmpty())
System.out.println((System.currentTimeMillis()-start)/1000);
Thread.sleep(delayFactor);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
メインスレッド:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class KafkaLoadBalancer {
private static int MAX_PARTITION = 4;
public static void main(String args[]) throws InterruptedException {
List<BlockingQueue<Integer>> blockingQueues = new ArrayList<>();
List<Integer> fullPartitions = new ArrayList<Integer>();
List<Integer> activePartitions = new ArrayList<Integer>();
System.out.println("Creating Queues");
for(int i=0;i<MAX_PARTITION;i++) {
blockingQueues.add(new ArrayBlockingQueue<>(1000000));
fullPartitions.add(i);
activePartitions.add(i);
}
System.out.println("Starting Producers");
for(int i=0;i<MAX_PARTITION;i++) {
Producer producer = new Producer(blockingQueues,fullPartitions,activePartitions);
new Thread(producer).start();
}
System.out.println("Starting Consumers");
for(int i=0;i<MAX_PARTITION;i++) {
Consumer consumer = new Consumer(blockingQueues.get(i),i+1,i);
new Thread(consumer).start();
}
System.out.println("Starting Display Thread");
DisplayQueue dq = new DisplayQueue(blockingQueues);
new Thread(dq).start();
}
}
DispayQueue:キューサイズを表示するには
import java.util.List;
import java.util.concurrent.BlockingQueue;
public class DisplayQueue implements Runnable {
private List<BlockingQueue<Integer>> blockingQueues;
public DisplayQueue(List<BlockingQueue<Integer>> blockingQueues) {
this.blockingQueues = blockingQueues;
}
@Override
public void run() {
long start = System.currentTimeMillis();
while(true) {
if(System.currentTimeMillis()-start>30000) {
for(int i=0;i<blockingQueues.size();i++)
System.out.println("Queue "+i+" size is=="+blockingQueues.get(i).size());
start = System.currentTimeMillis();
}
}
}
}