Documentation ¶
Overview ¶
package consistent 提供了一致性哈希的计算功能,以用于分布式请求的负载均衡。 比如有三台机器,分别为cacheA,cacheB,cacheC, 我们可以通过提供的功能来分配大量用户的大批量请求。
我们可以通过New来创建一致性哈希,通过Add、Remove来增加、删除服务器,通过Get来获取提供服务的物理机。 需要注意的是,如果增删服务器,hash值将会重新计算(remap),会造成注册的服务器重建相关业务。
相关技术的材料,可以查看:
wikipedia: http://en.wikipedia.org/wiki/Consistent_hashing csdn: http://blog.csdn.net/cywosp/article/details/23397179/ csdn: http://blog.csdn.net/caigen1988/article/details/7708806 go语言实现: https://segmentfault.com/a/1190000000414004
Index ¶
- Variables
- type Consistent
- func (c *Consistent) Add(elt string)
- func (c *Consistent) Get(name string) (string, error)
- func (c *Consistent) GetMachineNum() int
- func (c *Consistent) GetN(name string, n int) ([]string, error)
- func (c *Consistent) GetTwo(name string) (string, string, error)
- func (c *Consistent) Members() []string
- func (c *Consistent) Remove(elt string)
- func (c *Consistent) Set(elts []string)
- func (c *Consistent) SetReplicas(replicasNum int)
- Bugs
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrEmptyCircle = errors.New("empty circle")
ErrEmptyCircle is the error returned when trying to get an element when nothing has been added to hash.
Functions ¶
This section is empty.
Types ¶
type Consistent ¶
Consistent 通过成员变量,保留一致性哈希环的struct.
func NewConsistent ¶
func NewConsistent() *Consistent
NewConsistent 基于默认的replicas定义,创建一个新的对象。
要改变replicas的值,可以在添加服务器节点之前,通过SetReplicas方法修改。
Example ¶
package main import ( "fmt" "github.com/alex023/basekit/hash/consistent" "log" ) func main() { c := consistent.NewConsistent() c.Add("cacheA") c.Add("cacheB") c.Add("cacheC") users := []string{"user_mcnulty", "user_bunk", "user_omar", "user_bunny", "user_stringer"} for _, u := range users { server, err := c.Get(u) if err != nil { log.Fatal(err) } fmt.Printf("%s => %s\n", u, server) } }
Output: user_mcnulty => cacheA user_bunk => cacheA user_omar => cacheA user_bunny => cacheC user_stringer => cacheC
func (*Consistent) Add ¶
func (c *Consistent) Add(elt string)
Add 增加一个物理机到hash表中
Example ¶
package main import ( "fmt" "github.com/alex023/basekit/hash/consistent" "log" ) func main() { c := consistent.NewConsistent() c.Add("cacheA") c.Add("cacheB") c.Add("cacheC") users := []string{"user_mcnulty", "user_bunk", "user_omar", "user_bunny", "user_stringer"} fmt.Println("initial state [A, B, C]") for _, u := range users { server, err := c.Get(u) if err != nil { log.Fatal(err) } fmt.Printf("%s => %s\n", u, server) } c.Add("cacheD") c.Add("cacheE") fmt.Println("\nwith cacheD, cacheE [A, B, C, D, E]") for _, u := range users { server, err := c.Get(u) if err != nil { log.Fatal(err) } fmt.Printf("%s => %s\n", u, server) } }
Output: initial state [A, B, C] user_mcnulty => cacheA user_bunk => cacheA user_omar => cacheA user_bunny => cacheC user_stringer => cacheC with cacheD, cacheE [A, B, C, D, E] user_mcnulty => cacheE user_bunk => cacheA user_omar => cacheA user_bunny => cacheE user_stringer => cacheE
func (*Consistent) Get ¶
func (c *Consistent) Get(name string) (string, error)
Get 按照顺时针取值原则,获取name的哈希值最接近的物理服务器,即circle[i-1]<hash(name)<=circle[i],返回circle[i]对应的物理服务。
func (*Consistent) GetN ¶
func (c *Consistent) GetN(name string, n int) ([]string, error)
GetN returns the N closest distinct elements to the name input in the circle.
func (*Consistent) GetTwo ¶
func (c *Consistent) GetTwo(name string) (string, string, error)
GetTwo returns the two closest distinct elements to the name input in the circle.
func (*Consistent) Remove ¶
func (c *Consistent) Remove(elt string)
Remove removes an element from the hash.
Example ¶
package main import ( "fmt" "github.com/alex023/basekit/hash/consistent" "log" ) func main() { c := consistent.NewConsistent() c.Add("cacheA") c.Add("cacheB") c.Add("cacheC") users := []string{"user_mcnulty", "user_bunk", "user_omar", "user_bunny", "user_stringer"} fmt.Println("initial state [A, B, C]") for _, u := range users { server, err := c.Get(u) if err != nil { log.Fatal(err) } fmt.Printf("%s => %s\n", u, server) } c.Remove("cacheC") fmt.Println("\ncacheC removed [A, B]") for _, u := range users { server, err := c.Get(u) if err != nil { log.Fatal(err) } fmt.Printf("%s => %s\n", u, server) } }
Output: initial state [A, B, C] user_mcnulty => cacheA user_bunk => cacheA user_omar => cacheA user_bunny => cacheC user_stringer => cacheC cacheC removed [A, B] user_mcnulty => cacheA user_bunk => cacheA user_omar => cacheA user_bunny => cacheB user_stringer => cacheB
func (*Consistent) Set ¶
func (c *Consistent) Set(elts []string)
批量设置物理服务器到hash中。如果输入值与hash已经存在的值不一致,则以输入值为准。
Set sets all the elements in the hash. If there are existing elements not present in elts, they will be removed.
func (*Consistent) SetReplicas ¶
func (c *Consistent) SetReplicas(replicasNum int)
修改constent的replicas属性,务必在Add方法之前使用
Notes ¶
Bugs ¶
没有实现热替换。某台服务器失效后,hash值需要全部重新计算,导致业务系统影响很大。