(quote from github : https://github.com/RJ/ketama)
We wrote ketama to replace how our memcached clients mapped keys to servers. Previously, clients mapped keys->servers like this:
server = serverlist[hash(key)%serverlist.length];
This meant that whenever we added or removed servers from the pool, everything hashed to different servers, which effectively wiped the entire cache.
Ketama solves this problem in the following way:
We could dynamic set up the node weight and node copies, and you could save your current options in stash, and you can recovery your options at any time, you can also make an balance test to make sure the node weight are close to the actual situation
-record(ring_opt, { name :: atom(),
node_copies = 40 :: integer(),
expand_node = true :: boolean(),
match_operator = '>=' :: '>='| '>',
concat_char = ":" :: char(),
copies_gen_type = weight :: weight | specific}).
name: your ring name
node_copies:
only work when the copies_gen_type is weight, mutilple of nodes.
expand_node: the hash value of md5(key) was grouped by 16 bytes, and each four byte is a node hash key, if we only want use first 4 bytes, just disable this option.
match_operator:
an operator about ets match_spec.
concat_char:
if your hashseed is "ip:port", the copies hashseed is ip:port
+ concat_char
+ copy_id
copies_gen_type:
weight:auto compute the copies number
specific: manually set the copies number, but if the expand_node = true
, the copies number will be quadrupled
RingTest = #ring_opt{name = test, node_copies=80}.
#ring_opt{name = test,node_copies = 80,expand_node = true,
match_operator = '>=',concat_char = ":",
copies_gen_type = weight}
(ketama@ZhengXujin-PC)6> ketama:add_ring(RingTest).
ok
(ketama@ZhengXujin-PC)12> ketama:list_rings().
[#ring_opt{name = test,node_copies = 80,expand_node = true,
match_operator = '>=',concat_char = ":",
copies_gen_type = weight}]
(ketama@ZhengXujin-PC)13> ketama:get_ring_summary(test).
[#node_summary{id = 1,weight = 10,percentage = 0.2,
copies_num = 64},
#node_summary{id = 2,weight = 40,percentage = 0.8,
copies_num = 256}]
-record(node, {id :: integer(),
hash_seed :: string(),
weight :: integer(),
copies_num :: integer(),
object :: any()}).
id: nodeid
hash_seed: e.g.: "127.0.0.1:8080".
weight:
only work while copies_gen_type = weight
.
copies_num:
only work while copies_gen_type = weight
.
object: your customize value, the ketama:get_object(ringname, key) will return {ok, {NodeId, Object}}, then you can store your own data.
Node1 = #node{id=1, hash_seed = "127.0.0.1:8080", weight=10, object={a,b,c}}.
Node2 = #node{id=2, hash_seed = "127.0.0.1:8081", weight=40, object={a,b,e}}.
ketama:add_node(test, Node1).
ketama:add_node(test, Node2).
ketama:set_node_weight(test,1,100). %% work will gen_type == weight
ketama:set_node_copies(test,1,100). %% work will gen_type == specific
while you do some A/B testing about request, you may reduce the weight and add an node, then the tiny request will goto the testing server, but you also want to backup your current options that after the testing was finished, you could recovery by a stash.
-record(stash, { id :: atom(),
ring :: atom(),
name :: atom(),
nodes :: list(),
time = erlang:localtime()}).
ketama:stash(test,t1).
ketama:stash_apply(test,t1).
ketama:remove_stash(test,t1).
ketama:remove_stashes(test).
ketama:list_stashes().
ketama:list_stashes(test).
ketama:get_stash(test,t1).
while you set up the weight of the node, you may ask a question, do really this weight works fine? So, lets do a balance test!
ketama:balance_test(ring_name, TestKeyNumber).
you'd better set a big TestKeyNumber
, for example : 1000000, then this function will give are real node hit report like this:
(ketama@ZhengXujin-PC)11> ketama:get_ring_summary(test).
[#node_summary{id = 1,weight = 10,percentage = 0.2,
copies_num = 64},
#node_summary{id = 2,weight = 40,percentage = 0.8,
copies_num = 256}]
(ketama@ZhengXujin-PC)10> ketama:balance_test(test, 1000).
{ok,[{2,{781,0.781}},{1,{219,0.219}}]}
it means node 1 hitted 219 times, and the percentage is 21.9%, the node 2 hitted 781 times, and the percentage is 78.1%. So, lets look at the configurate(ketama:get_ring_summary), the results are very similar.
note: if you find the resaults are not smimilar to your configure, you should increase your node_copies(weight mode) or copies_num(specific mode)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。