「架构师训练营」作业:第 5 周 一致性 hash 算法
发布于: 2020 年 07 月 08 日
用你熟悉的编程语言实现一致性 hash 算法
编写测试用例测试这个算法,测试 100 万 kv 数据,10 个服务器节点的情况下,计算这些 kv 数据在服务器上分布数据的标准差,以评估算法的存储负载不均衡性。
语言:C#
IDE:Visual Studio 2019
Sdk:.net core 3.1
class Program{ private static readonly SortedDictionary<ulong, string> _circle = new SortedDictionary<ulong, string>(); public static string[] services = new string[] { "192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4", "192.168.1.5", "192.168.1.6", "192.168.1.7", "192.168.1.8", "192.168.1.9", "192.168.1.10" }; static void Main(string[] args) { int Replicas = 100; foreach(string ip in services) { AddNode(ip, Replicas); } List<string> nodes = new List<string>(); for (int i = 0; i < 1000000; i++) { nodes.Add(GetTargetNode(i + "test" + (char)i)); } var counts = nodes.GroupBy(n => n, n => n.Count()).ToList(); counts.ForEach(index => Console.WriteLine(index.Key + " --- " + index.Count())); var stdDeviation = CaculateStandardDeviation(counts.Select(i => i.Count()).ToArray()); Console.WriteLine(); Console.WriteLine("标准差:{0}",stdDeviation.ToString()); Console.ReadLine(); } public static void AddNode(string node, int repeat) { for (int i = 0; i < repeat; i++) { string identifier = node.GetHashCode().ToString() + "-" + i; ulong hashCode = Md5Hash(identifier); _circle.Add(hashCode, node); } } public static ulong Md5Hash(string key) { using (var hash = System.Security.Cryptography.MD5.Create()) { byte[] data = hash.ComputeHash(Encoding.UTF8.GetBytes(key)); var a = BitConverter.ToUInt64(data, 0); var b = BitConverter.ToUInt64(data, 8); ulong hashCode = a ^ b; return hashCode; } } public static string GetTargetNode(string key) { ulong hash = Md5Hash(key); ulong firstNode = ModifiedBinarySearch(_circle.Keys.ToArray(), hash); return _circle[firstNode]; } /// <summary> /// 计算key的数值,得出空间归属。 /// </summary> /// <param name="sortedArray"></param> /// <param name="val"></param> /// <returns></returns> public static ulong ModifiedBinarySearch(ulong[] sortedArray, ulong val) { int min = 0; int max = sortedArray.Length - 1; if (val < sortedArray[min] || val > sortedArray[max]) return sortedArray[0]; while (max - min > 1) { int mid = (max + min) / 2; if (sortedArray[mid] >= val) { max = mid; } else { min = mid; } } return sortedArray[max]; } public static double CaculateStandardDeviation(int[] arry) { double stdDeviation = 0; int min = arry.Min(); int max = arry.Max(); var avg = Math.Round((decimal)arry.Average(p => p), 5); if (arry.Length > 1) { double sumOfSquare = 0; foreach(var item in arry) { sumOfSquare += Math.Pow((double)item - (double)avg, 2); } stdDeviation = Math.Sqrt(sumOfSquare / (arry.Length - 1)); stdDeviation = Math.Round(stdDeviation, 5); } return stdDeviation; }}
划线
评论
复制
发布于: 2020 年 07 月 08 日 阅读数: 37
Amy
关注
还未添加个人签名 2018.06.10 加入
还未添加个人简介
评论