什么是 hash 一致性算法
hash 一致性算法其实是一种分区器的解决方案。大家都使用 HashMap 。它通过根据 key 的 hash 值,将 entry 分发到数据的某个位置上,相同的 key 可以分配到相同的位置上。在分布式中,一个特性被使用到了 MapReduce,实现相同 key 的聚集。应用到 redis 中,实现数据较平均的分配到 redis 集群的各个节点。
这就是 hash 值的魅力。
使用 Java 实现 hash 一致性算法
为了更好的理解和记忆 hash 一致性算法,使用 Java 实现了此算法。
实现的主体类:
import java.util.Arrays;
import java.util.Objects;
/**
* @className: HashConsistence
* @Description:
* @Author: wangyifei
* @Date: 2023/2/28 10:53
*/
public class HashConsistence {
private int HASHC_CIRCLE_SIZE = (2 << 16 ) - 1;
private String HOST_PREDIX = "host_";
private int HOST_SIZE ;
/**
* 使用 int 类型的数组来模拟 hash 环的结构,
* hashCircle[N] 代表 hostname.haashcode%host_size = N 的机器编号
* */
private HostNode[] hashCircle = new HostNode[HASHC_CIRCLE_SIZE];
public HostNode[] getHashCircle() {
return hashCircle;
}
public void setHashCircle(HostNode[] hashCircle) {
this.hashCircle = hashCircle;
}
public void putNodeIntoHashCircle(HostNode node){
int idx = Math.abs(node.getHostName().hashCode()%HASHC_CIRCLE_SIZE);
hashCircle[idx] = node ;
}
public int router(KeyValue kv){
int hashValue = Math.abs(kv.getKey().hashCode()%HASHC_CIRCLE_SIZE);
int routerIndex = -1 ;
System.out.println(hashValue);
for (int i = hashValue ; i < HASHC_CIRCLE_SIZE ; i++){
if(!Objects.isNull(hashCircle[i])){
routerIndex = i ;
}
}
return routerIndex ;
}
public static void main(String[] args) {
HashConsistence hashConsistence = new HashConsistence();
for (int i = 0; i < 100; i++) {
hashConsistence.putNodeIntoHashCircle(new HostNode("host" + i , "192.168.11."+ i , HostState.ACTIVE));
}
int wangyifei = hashConsistence.router(new KeyValue("wangyifei", new Object()));
System.out.println(wangyifei);
}
}
下面是 bean 类:
/**
* @className: HostNode
* @Description: 代表 redis 的节点
* @Author: wangyifei
* @Date: 2023/2/28 11:02
*/
public class HostNode {
private String hostName ;
private String IP ;
private HostState state ;
public HostNode(String hostName , String IP , HostState state){
this.hostName = hostName ;
this.IP = IP ;
this.state = state ;
}
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
public String getIP() {
return IP;
}
public void setIP(String IP) {
this.IP = IP;
}
public HostState getState() {
return state;
}
public void setState(HostState state) {
this.state = state;
}
@Override
public String toString() {
return "HostNode{" +
"hostName='" + hostName + '\'' +
", IP='" + IP + '\'' +
", state=" + state +
'}';
}
}
/**
* @className: HostState
* @Description: 代表了节点的状态
* @Author: wangyifei
* @Date: 2023/2/28 11:03
*/
public enum HostState {
ACTIVE,INACTIVE
}
/**
* @className: KeyValue
* @Description: 代表了 k-v 结构
* @Author: wangyifei
* @Date: 2023/2/28 14:05
*/
public class KeyValue {
private String key ;
private Object value ;
public KeyValue(String key , Object value){
this.key = key ;
this.value = value ;
}
@Override
public String toString() {
return "KeyValue{" +
"key='" + key + '\'' +
", value=" + value +
'}';
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}