首页 > 其他 > 详细

Consistent HASH(自己读后理解)

时间:2014-02-20 02:10:54      阅读:387      评论:0      收藏:0      [点我收藏+]

一致性HASH, 作用在于当有服务器实效的情况下,保持CACHE的一致性.避免引起大量读CACHE失效.

假设服务部分的架构如下: appServer(10台)--- servicesServer(3台)---Database(2台 master,slave)

servicesServer有相关用户数据的CACHE, 通过id模servicesServerNum映射到相应的servicesServer上。 假设 有用户 1 到 3 访问某个页面,即用户(u1,u2,u3)访问 appServer. appServer通过接口调用访问servicesServer,用户0的CACHE在servicesServer0上,以此类推.

可是天有不测风云, servicesServer0因为磁盘问题挂掉了,现在会出现什么情况呢?

由于我们通过 id模servicesServerNum映射得到相应的servicesServer,但是现在只有2台机器了, 于是 :

before servicesServer0 down: (0--s0, 1--s1, 2--s2)

u1 1mod3--> s1

u2 2mod3--> s2

u3 3mod3--> s0

after servicesServer0 down(0--s1, 1--s2)

u1 1mod2--> s2  change

u2 2mod2--> s1 change

u3 3mod2--> s2  change

在这种情况下,原来的CACHE全部失效, 所有的读请求全部瞬间压倒Database上面。

一致性CACHE就是为了解决这个问题提出来的。它不是直接的取模映射,而是将一个区间影射到特定服务器上,这样即使机器减少或者增加,大部分的CACHE仍然能够有效,避免了瞬间的冲击。 为了更好的平衡CACHE的分布,还引入了虚拟节点的概念,一个实际的节点,可以化生为多个不同的虚拟节点,这样能够让区间映射更加平衡。 下面是我测试的代码 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
class Program
{
    BNode[] _BNodes;
    int _ArrayLength;
 
    static void Main(string[] args)
    {
        Program ptest = new Program();
        ptest.InitArray(5, 4);
        ptest.ShowNodes(5,4);
 
        ptest.SortArray();
 
        int restring = ptest.BserachServer(3);
 
        restring = ptest.BserachServer(152);
 
        restring = ptest.BserachServer(155);
 
        restring = ptest.BserachServer(0);    
         
    }
 
    void InitArray(int RealNodeNum, int VirtualCopyNum)
    {
        int totalNum = RealNodeNum * VirtualCopyNum ;
        _BNodes =  new BNode[totalNum];
        _ArrayLength = totalNum;
 
        for (int i = 0; i < RealNodeNum; i++)
        {
            for(int j = 0; j < VirtualCopyNum ; j++)
            {
                BNode tempNode = new BNode();
                tempNode.IPAddr = "172.16.73." + (i+1);
                tempNode.hashcode = ( "V" + j + tempNode.IPAddr ).GetHashCode();
                //Console.Out.WriteLine(tempNode.hashcode);
                tempNode.flag = 1;
                //Console.Out.WriteLine(tempNode.hashcode);
                _BNodes[i] = tempNode;
            }
        }
    }
 
    void ShowNodes(int RealNodeNum, int VirtualCopyNum)
    {
        int totalNum = RealNodeNum * VirtualCopyNum;
        for (int i = 0; i < totalNum; i++)
        {
            Console.Out.Write(_BNodes[i].hashcode + " ");
            Console.Out.Write(_BNodes[i].flag + " ");
            Console.Out.WriteLine(_BNodes[i].IPAddr);
        }
    }
 
    bool DelOneNode(int machineID, int VirtualCopyNum)
    {
        int i = machineID;
        for (int j = 0; j < VirtualCopyNum; j++)
        {
            string IPAddr = "172.16.73." + (i + 1);
            int hashcode = ("V" + j + IPAddr).GetHashCode();
            BNode delNode = BserachNode(hashcode);
            if (delNode != null)
            {
                delNode.flag = 0;
            }
        }
        return true;
    }
 
    int FindNode(int objectHashCode)
    {
        int pos = BserachServer(objectHashCode);
        int tempos = pos;
        int cycleFlag =0;
        while ( !( tempos == pos && cycleFlag == 1) )
        {
            if (_BNodes[pos].flag > 0)
            {
                return pos;
            }
            else
            {
                if (pos == 0)
                {
                    pos = _ArrayLength-1;
                    cycleFlag = 1;
                }
                pos = pos - 1;
                 
            }
        }
        return 0;
    }
 
    void SortArray()
    {
        ShowNodes(5, 4);
        IComparer myComparer = new myCompareClass();
        Array.Sort(_BNodes, myComparer);
        ShowNodes(5, 4);
    }
 
    int BserachServer(int cmphashcode)
    {
        if (_BNodes[_ArrayLength - 1].hashcode <= cmphashcode || _BNodes[0].hashcode > cmphashcode)
        {
            return _ArrayLength - 1;
        }
 
        {
            int lowPos = 0;
            int highPos = _ArrayLength;
            int middlePos = (lowPos + highPos) / 2;
 
            while (true)
            {
                middlePos = (lowPos + highPos) / 2;
                if (middlePos < lowPos )
                {
                    return middlePos;
                }
 
                if (lowPos > highPos)
                {
                    return middlePos;
                }
                 
 
                if (cmphashcode < _BNodes[middlePos].hashcode)
                {
                    highPos = middlePos - 1;
                }
                else if (cmphashcode > _BNodes[middlePos].hashcode)
                {
                    lowPos = middlePos + 1;
                }
                else
                {
                    return middlePos;
                }
            }
        }
    }
 
    BNode BserachNode(int cmphashcode)
    {
        int lowPos = 0;
        int highPos = _ArrayLength;
        int middlePos = (lowPos + highPos) / 2;
 
        while (middlePos < lowPos || lowPos > highPos)
        {
            middlePos = (lowPos + highPos) / 2;
 
            if (cmphashcode < _BNodes[middlePos].hashcode)
            {
                highPos = middlePos - 1;
            }
            else if (cmphashcode > _BNodes[middlePos].hashcode)
            {
                lowPos = middlePos + 1;
            }
            else
            {
                return _BNodes[middlePos];
            }
        }
        return null;
    }
 
    internal class BNode
    {
        public int     hashcode;
        public string  IPAddr;
        public int     flag;
    }
 
    internal class myCompareClass : IComparer
    {
         int IComparer.Compare(object x, object y)
        {
            if (((BNode)x).hashcode == ((BNode)y).hashcode)
            {
                return 0;
            }
            else if (((BNode)x).hashcode > ((BNode)y).hashcode)
            {
                return 1;
            }
            else
                return -1;
 
        }
    }
 
}

  

Consistent HASH(自己读后理解)

原文:http://www.cnblogs.com/cquccy/p/3556118.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!