您的位置:首页 > 教育 > 培训 > 电商平台是干什么的_自媒体平台企业网站怎么设置_今日新闻_win7系统优化

电商平台是干什么的_自媒体平台企业网站怎么设置_今日新闻_win7系统优化

2025/3/13 19:43:34 来源:https://blog.csdn.net/qq_41893505/article/details/146216358  浏览:    关键词:电商平台是干什么的_自媒体平台企业网站怎么设置_今日新闻_win7系统优化
电商平台是干什么的_自媒体平台企业网站怎么设置_今日新闻_win7系统优化

一致性哈希是一种特殊的哈希算法,主要用于分布式系统,解决数据分布和节点动态变化的问题。相比传统哈希算法,它能够有效减少因服务器扩容或缩容导致的缓存重建问题,广泛应用于分布式缓存、分布式存储、负载均衡等场景。

1. 传统哈希 vs 一致性哈希

(1)传统取模哈希

在常规哈希方案中,我们通常使用取模算法进行分片:
[
\text{server} = \text{hash}(\text{key}) \mod N
]
其中 ( N ) 是服务器的总数。例如:

  • 假设有 3 台服务器(编号 0、1、2),对数据 user123 进行哈希:

    server = hash("user123") % 3 = 1
    

    数据 user123 存在 Server 1

  • 问题:扩容或缩容时,大量数据需要迁移

    • 例如:如果扩容到 4 台服务器,原本的 mod 3 变成 mod 4,那么所有数据的存储位置都会变化,大量数据需要重新分配,造成 缓存雪崩

(2)一致性哈希

一致性哈希使用哈希环的概念,减少数据迁移:

  1. 将服务器映射到一个固定的哈希环(0 ~ 2³² - 1)。
  2. 对每个数据计算哈希值,并放入顺时针方向的最近服务器
  3. 扩容/缩容时,只影响哈希环上的局部数据,减少数据迁移量。

2. 一致性哈希的实现

(1)哈希环

  • 使用一个 0 ~ 2³²-1哈希空间,并将服务器的哈希值映射到该空间上。
  • 数据的哈希值也映射到该空间,并顺时针找到最近的服务器存储数据。

示例:
假设有 3 台服务器:

Server A -> hash(A) = 10
Server B -> hash(B) = 30
Server C -> hash(C) = 60

当数据 key123 进行哈希:

hash(key123) = 25   →  由于 25 在 (10, 30] 区间,存入 Server B

(2)服务器增减对数据影响

  • 扩容

新增 Server D (hash(D) = 20) 后,落在 (10, 20] 之间的数据会从 Server B 迁移到 Server D,而 hash(key123) = 25 不受影响,仍然在 Server B 上,只影响 Server D 和 Server B 之间的数据。

  • 缩容:如果 Server B 挂掉,则 hash(key123) = 25 顺时针找到 Server C,同样只影响部分数据

3. 虚拟节点(解决数据倾斜问题)

问题:服务器分布不均匀,导致数据倾斜

  • 如果 3 台服务器 A (10), B (30), C (60),但 A-C 之间间距大,那么 C 可能存储的数据远多于 A、B。

解决方案:使用虚拟节点

  • 在环上为每台服务器创建多个虚拟副本(通过不同哈希计算),均匀分布:
    Server A -> hash(A#1) = 10, hash(A#2) = 15, hash(A#3) = 20
    Server B -> hash(B#1) = 30, hash(B#2) = 35, hash(B#3) = 40
    
    这样可以使服务器负载均衡,避免某个服务器存储过多数据。

4. 一致性哈希的应用

  1. 分布式缓存(Redis, Memcached)
    • 一致性哈希用于 Redis 缓存集群,减少缓存失效的影响。
  2. 分布式存储(HDFS, Ceph)
    • 存储节点的动态调整不会影响整个集群。
  3. 负载均衡(Nginx, LVS)
    • 反向代理服务器使用一致性哈希进行请求分配。
  4. 分布式数据库(ShardingSphere, MySQL 分片)
    • 数据库分片采用一致性哈希,避免大规模数据迁移。

5. Java 实现一致性哈希

(1)基本实现

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.SortedMap;
import java.util.TreeMap;public class ConsistentHashing {private final TreeMap<Integer, String> ring = new TreeMap<>();private final int virtualNodes = 3; // 虚拟节点个数public void addServer(String server) {for (int i = 0; i < virtualNodes; i++) {int hash = hash(server + "#" + i);ring.put(hash, server);}}public void removeServer(String server) {for (int i = 0; i < virtualNodes; i++) {int hash = hash(server + "#" + i);ring.remove(hash);}}public String getServer(String key) {if (ring.isEmpty()) return null;int hash = hash(key);SortedMap<Integer, String> tailMap = ring.tailMap(hash);Integer targetHash = tailMap.isEmpty() ? ring.firstKey() : tailMap.firstKey();return ring.get(targetHash);}private int hash(String key) {try {MessageDigest md = MessageDigest.getInstance("MD5");byte[] bytes = md.digest(key.getBytes(StandardCharsets.UTF_8));return ((bytes[0] & 0xFF) << 24) | ((bytes[1] & 0xFF) << 16) | ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF);} catch (Exception e) {throw new RuntimeException(e);}}public static void main(String[] args) {ConsistentHashing ch = new ConsistentHashing();ch.addServer("ServerA");ch.addServer("ServerB");ch.addServer("ServerC");System.out.println("key123 存入: " + ch.getServer("key123"));System.out.println("key456 存入: " + ch.getServer("key456"));ch.addServer("ServerD");System.out.println("扩容后 key123 存入: " + ch.getServer("key123"));}
}

6. 总结

适用于分布式系统,解决服务器动态变更导致的数据迁移问题。
比取模哈希更稳定,减少缓存击穿问题。
结合虚拟节点可以均衡负载,避免数据倾斜。
仍然存在一定的计算开销,尤其是哈希计算和虚拟节点管理。

一致性哈希广泛应用于分布式存储、负载均衡、分布式数据库等场景,是现代分布式架构中不可或缺的技术。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com