写点什么

架构师 1 期 - 技术选型 (一) 作业

用户头像
ltl3884
关注
发布于: 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 个节点是比较合理的


用户头像

ltl3884

关注

还未添加个人签名 2017.12.08 加入

还未添加个人简介

评论

发布
暂无评论
架构师1期-技术选型(一)作业