0

I have a cluster of c-nodes that connect to my erlang instance and need to have messages distributed amongst them. My current method of doing this is to have a -define of the list of cnode name atoms, and a gen_server which simply responds to request for the names by rotating the list and sending back whatever is currently at the front, and the requesting process then interacts with whatever node it was given. Unfortunately these c-nodes are very heavily used and that gen_server is backing up significantly (staying at around 2k-6k messages in its queue).

I'm wondering if there's any other way I could "load balance" across these c-nodes. My initial thought was to just pick a random element from the list whenever a process needs to interact with one, but that seems extremely inefficient to me. Are there any other methods I'm not thinking of?

4

1 回答 1

3

There are a few other methods you could try out:

  1. Hashing - you take a client id or something unique and hash it over the list of down stream servers to pick
  2. Round Robin - you store all down stream servers in an ets table and keep a last accessed tuple with them. You then grab all servers from the ets table and find the least recently used, updating the field at the same time.
  3. Random - just pick one.

But I'm going to have to agree with Saurabh Barjatiya.

不要在没有运行...基准的情况下放弃随机分布。

我有一个生产系统,我们尝试在其中进行循环负载平衡,因为我认为随机分区太“低效”并且对于我们需要的不够“平滑”。

在完成了一些不同的解决方案(ets表、散列、gen_server 的东西主要是上述三个以及其他一些非常令人尴尬的解决方案)之后,我尝试了以下方法,因为它知道它不会很好地工作:

Count = length(Targets),
random:seed(now()),
Route = lists:nth(random:uniform(Count),Targets),

在本地测试之后,然后在生产系统中,结果证明它足够快(如果不是最快的话),并且它分发的所有东西都足够平滑以满足我们的需要,并且因此我们没有任何性能问题。

In general don't make the same mistake I did and waste time optimizing complicating code that does not need to be optimized. Always benchmark a solution to really see if your assumptions are correct.

于 2013-10-14T21:49:56.430 回答