架构师 1 期 - 技术选型 (一) 作业
发布于: 2020 年 10 月 24 日
我使用 ruby 实现一致性 hash
首先实现一个虚拟节点的类
module ConsistentHashing class VirtualPoint attr_reader :node, :index
def initialize(node, index) @node = node @index = index.to_i end
def index=(index) @index = index.to_i end endend复制代码
一致性 hash 的主要逻辑
module ConsistentHashing
class Ring
def initialize(nodes = [], replicas = 3) @replicas = replicas @ring = AVLTree.new
nodes.each { |node| add(node) } end
def add(node) @replicas.times do |i| key = hash_key(node, i) @ring[key] = VirtualPoint.new(node, key) end end
def delete(node) @replicas.times do |i| key = hash_key(node, i) @ring.delete key end end
def point_for(key) return nil if @ring.empty? key = hash_key(key) _, value = @ring.next_gte_pair(key) _, value = @ring.minimum_pair unless value value end
def node_for(key) point_for(key).node end
protected
def hash_key(key, index = nil) key = "#{key}:#{index}" if index Digest::MD5.hexdigest(key.to_s)[0..16].hex end endend
复制代码
数组搜索大于等于目标值的最小值节点比较慢,改为 AVLTree 的 #next_gte_pair 方法
require 'consistent_hashing'require 'descriptive_statistics'
servers = [](0..9).each do |i| servers << "192.168.1.10#{i}"end
(1..20).each do |time| h_count = {} ring = ConsistentHashing::Ring.new(servers, time) (1..1000000).each do |i| n = "n#{i}" server = ring.node_for(n) if h_count[server].nil? h_count[server] = 1 else h_count[server] += 1 end end puts ring.points.size puts h_count.values.standard_deviationend复制代码
100 万数据测试程序 10 个节点标准差 74545
100 万数据测试程序 100 个节点标准差 26218
100 万数据测试程序 150 个节点标准差 20409
之后一直是在 20000 上下
说明 150 个节点是比较合理的
划线
评论
复制
发布于: 2020 年 10 月 24 日阅读数: 36
ltl3884
关注
还未添加个人签名 2017.12.08 加入
还未添加个人简介











评论