ngx_lua出来很长时间了,但一直没有关注过,最近有一个I/O密集型的项目,用PHP性能严重不足,但是通过C开发扩展成本很大,对需求也不能及时响应,结果尝试了一下lua,结果非常喜人,他的同步非阻塞I/O,协同程序等等,让他的性能无与伦比!
在项目的开发中需要用到consistent hash来保证缓存的可靠性,所以就写了一个hash算法,跟大家分享一下,这是第一版,希望大家多提意见:
详细介绍请看https://github.com/qiaodandedidi/ngx_lua_consistent/wiki
--[[
-- consistent hash
--
-- @author wjw@qudapin.com
--]]
do
-- virtual nodes number
local VIRTUAL_COUNT = 160;
-- sharding vaitual nodes number
local CONSISTENT_BUCKETS = 1024;
-- the table of virtual nodes
local VIRTUAL_NODE = {};
-- the talbe of sharding
local BUCKETS = {};
-- module of consistent
local _M = {};
-- crc32 algorithm
local crc32 = function(arg) return math.abs(ngx.crc32_long(arg)) end
--[[
-- add servers and to generate the ‘BUCKETS‘
--
-- @param {table} server all of the servers
-- ]]
function _M.add_server(server)
for i,v in pairs(server) do
for n=1,math.floor(VIRTUAL_COUNT) do
local hash_key = v..‘-‘..(n-1);
table.insert(VIRTUAL_NODE, {v, crc32(hash_key)});
end
end
-- sorting by ‘crc32(hash_key)‘, it means arg[2]
table.sort(VIRTUAL_NODE, function (arg1, arg2)
return (arg1[2] < arg2[2]);
end);
-- sharding
local slice = math.floor(0xFFFFFFFF / CONSISTENT_BUCKETS);
for i=1, CONSISTENT_BUCKETS do
table.insert(BUCKETS, i, hash_find(math.floor(slice * (i -1)), 1, #VIRTUAL_NODE));
end
end
--[[
-- Binary search
--
-- @param {float} key the value of we are looking for
-- @param {float} lo first index
-- @param {float} hi last index
-- @return {table} the node
--]]
function hash_find(key, lo, hi)
if key <= VIRTUAL_NODE[lo][2] or key > VIRTUAL_NODE[hi][2] then
return VIRTUAL_NODE[lo];
end
local middle = lo + math.floor((hi - lo) / 2);
if middel == 1 then
return VIRTUAL_NODE[middle];
elseif key <=VIRTUAL_NODE[middle][2] and key > VIRTUAL_NODE[middle-1][2] then
return VIRTUAL_NODE[middle];
elseif key > VIRTUAL_NODE[middle][2] then
return hash_find(key, middle+1, hi);
end
return hash_find(key, lo, middle-1);
end
--[[
-- get consistent hash value
--
-- @param {string} key
-- @return {string} node
--]]
function _M.get_upstream(key)
return BUCKETS[(crc32(key) % CONSISTENT_BUCKETS) + 1][1];
end
return _M;
end本文出自 “村长爱技术” 博客,请务必保留此出处http://weijingwu.blog.51cto.com/8376555/1559685
原文地址:http://weijingwu.blog.51cto.com/8376555/1559685