redis的双重hash作用

Redis 的双重哈希(Double Hashing)通常是指在 Redis 集群中使用的一种数据分片和节点定位机制。这种机制主要包含两个哈希步骤:

  1. 第一层哈希:使用 CRC16 算法对键(key)进行哈希,然后对 Redis 集群的哈希槽(hash slots)数量进行取模,从而将键映射到一个特定的哈希槽。
  2. 第二层哈希:当需要重新分片或者节点增加/减少时,为了保证数据迁移的最小化,Redis 集群使用虚拟节点(virtual nodes)的概念。每个物理节点可以有多个虚拟节点,每个虚拟节点也是一个哈希槽。这样,键通过第一层哈希确定的哈希槽可能会映射到不同的虚拟节点上,而这些虚拟节点再映射到实际的物理节点上。

双重哈希的优势包括:

  • 均匀分布:通过双重哈希,可以更均匀地将数据分布到各个节点,减少某些节点过载而其他节点空闲的情况。
  • 容错性:当某个节点失败时,只有映射到该节点的哈希槽需要重新分配,而不是整个键空间,这样可以减少数据迁移的开销。
  • 灵活性:在增加或减少节点时,只需要重新分配部分哈希槽,而不是全部,这样可以减少数据迁移的开销,提高系统的灵活性。

此外,Redis 集群使用这种机制可以实现数据的高可用性和可扩展性,同时保持较低的数据迁移成本和较高的数据访问效率。

原子性

Lua 本身并没有提供对于原子性的直接支持,它只是一种脚本语言,通常是嵌入到其他宿主程序中运行,比如 Redis。在 Redis 中执行 Lua 脚本的原子性是指:整个 Lua 脚本在执行期间,不会被其他客户端的命令打断。

这意味着,当 Redis 执行 Lua 脚本时,Redis 会把 Lua 脚本作为一个整体并把它当作一个任务加入到一个队列中,然后单线程按照队列的顺序依次执行这些任务,在执行过程中 Lua 脚本是不会被其他命令或请求打断,因此可以保证每个任务的执行都是原子性的。

例如,假设我们要将某个值加上1,并且只有在这个值小于10的情况下才能执行加1操作,那么可以使用一下 Lua 脚本来实现:

lua 复制代码
if redis.call('GET', 'value') < 10 then
    redis.call('INCR', 'value')
return 1
else
return 0
end

在redis中整个 Lua 脚本作为一个整体被执行且不被其他事务打断,这就是一个原子性的操作。

此外,Redis 通过 eval、evalsha 等命令来执行 Lua 脚本。但是,Lua 脚本如何保证原子性呢?在 Redis 中,Lua 脚本能够保证原子性的主要原因还是 Redis 采用了单线程执行模型。也就是说,当 Redis 执行 Lua 脚本时,Redis 会把 Lua 脚本作为一个整体并把它当作一个任务加入到一个队列中,然后单线程按照队列的顺序依次执行这些任务,在执行过程中 Lua 脚本是不会被其他命令或请求打断,因此可以保证每个任务的执行都是原子性的。

总结来说,在 Redis 中,Lua 脚本的原子性是由 Redis 的单线程执行模型保证的,这使得 Lua 脚本在执行期间不会被其他客户端的命令打断,从而确保了操作的原子性。

redis管道:就是相当于队列,开启一个管道传入多条redis命令可以实现串行化执行。

redis的事务是弱事务,可以通过使用lua增强事务

虚拟节点机制通过引入额外的虚拟节点来提高数据分布的均匀性。在一致性哈希算法中,每个节点(或服务器)和每个键(或数据)都被映射到一个哈希环上。数据通常被存储在环上顺时针方向遇到的第一个节点上。如果没有虚拟节点,当节点数量较少时,数据可能会非常不均匀地分布在节点上,导致某些节点过载而其他节点空闲。

通过引入虚拟节点,可以使得数据在节点间分布得更加均匀。每个物理节点可以有多个虚拟节点,这些虚拟节点在哈希环上均匀分布。当定位数据时,首先根据键的哈希值找到对应的虚拟节点,然后根据虚拟节点映射到实际的物理节点上。

这样做的好处包括:

  1. 提高系统的稳定性:即使在节点增减的情况下,也可以保证数据分布的相对稳定。
  2. 减少对系统的冲击:在节点变化时,只有部分数据需要迁移,从而减少了对系统的冲击。
  3. 数据均匀分布:通过虚拟节点,可以使得数据在节点间分布得更加均匀。

实际作用:如果一个物理节点对应多个虚拟节点,那么这些虚拟节点均匀分布在哈希环上,当增加或减少节点时,只有与这些虚拟节点相关联的数据需要重新分配,而不是整个键空间。这样可以减少数据迁移的开销,提高系统的灵活性。 总结来说,虚拟节点通过在哈希环上创建更多的节点位置,使得数据可以更加均匀地分布在各个物理节点上,从而提高了数据分布的均匀性,并且在节点增减时减少了数据迁移的开销。

相关推荐
dazhong201227 分钟前
PLSQL 客户端连接 Oracle 数据库配置
数据库·oracle
了一li3 小时前
Qt中的QProcess与Boost.Interprocess:实现多进程编程
服务器·数据库·qt
码农君莫笑3 小时前
信管通低代码信息管理系统应用平台
linux·数据库·windows·低代码·c#·.net·visual studio
别致的影分身3 小时前
使用C语言连接MySQL
数据库·mysql
京东零售技术5 小时前
“慢”增长时代的企业数据体系建设:超越数据中台
数据库
sdaxue.com5 小时前
帝国CMS:如何去掉帝国CMS登录界面的认证码登录
数据库·github·网站·帝国cms·认证码
o(╥﹏╥)6 小时前
linux(ubuntu )卡死怎么强制重启
linux·数据库·ubuntu·系统安全
阿里嘎多学长6 小时前
docker怎么部署高斯数据库
运维·数据库·docker·容器
Yuan_o_6 小时前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端
Sunyanhui16 小时前
牛客网 SQL36查找后排序
数据库·sql·mysql