ngx_lua出来很长时间了,但一直没有关注过,最近有一个I/O密集型的项目,用PHP性能严重不足,但是通过C开发扩展成本很大,对需求也不能及时响应,结果尝试了一下lua,结果非常喜人,他的同步非阻塞I/O,协同程序等等,让他的性能无与伦比!
在项目的开发中需要用到consistent hash来保证缓存的可靠性,所以就写了一个hash算法,跟大家分享一下,这是第一版,希望大家多提意见:
详细介绍请看https://github.com/qiaodandedidi/ngx_lua_consistent/wiki
--[[ -- consistent hash -- -- @author [email protected] --]] 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
时间: 2024-10-28 02:25:39