【Redis】map实现原理

哈希表是一个很常用的数据结构,不同的平台对它有不同的实现。下面是redis的实现。

首先是redis中与哈希表有关的数据结构定义。

节点定义:

这里有next指针的存在说明这是一个采用拉链法构建的哈希表。key是键,值是一个union,可以是以下的任意一种类型:指针,uint64和int64类型。

下面是table的实现:

一个ht结构体就是哈希表的一个容器数组。table是一个指针的数组,每一个元素都指向了一个Entry节点。size是table的大小,sizemask是获取索引的掩码,userd是键值对的数目。

最后就是整个哈希表的实现:

哈希表肯定需要一个table实例存放元素,但是这里是ht[2],表明有两个table,这与redis哈希表的扩容有关。包括最后的trehashids属性。还有一个type的指针,这个是与多态有关的,redis每一种数据类型都定义了一套方法,这些方法有:

因为不同的类型的这些方法的实现时不同的,比如计算哈希值就不同,所以要为每一种类型定义一套方法。在java里面,因为是由对象类型或者class存在的,所以可以很方便地使用多态来达到这个目的,但是在c语言里面,实现就比较困难。

在不进行rehash的正常情况下,哈希表里面只有ht[0]是有用的,ht[1]是空的。

所以哈希表的这样的:

redis使用的是murmurHash哈希算法。

下面是redis rehash的实现。

大致过程如下:

(1)为ht[1]分配空间,分配空间的大小是第一个大于ht[0].used*2的2的n次方,所以说table的大小是2的n次方,至于为什么,只要是为了用掩码算索引是保证均匀性。

(2)把ht[0]里面的元素全部rehash到ht[1],释放ht[0]的空间,让ht[0]指向ht[1],再为ht[1]重新指向一个新的空的table。

其实看到这里,redis的实现与java的区别并没有特别大,只不过java里面没有设置两个table,而只是在resize函数里面直接新建一个局部的数组,rehash,再重新让table指向了新的数组,大致的过程一样。

 

但是,redis在做rehash的具体步骤与java不同。我们知道如果哈希表的元素非常多,那么做一次rehash会很耗时,java的hashmap就是一次性做完全部的rehash,肯定会有性能问题,而redis不是一次性rehash的,redis的做法叫做渐进式rehash,把每一个槽位的链表的rehash操作平摊到每一次对哈希表的操作上,其中dict结构中trehashidx就是指向了下一个需要rehash的槽位的索引,只要处于rehash的过程中,那么这个属性就是大于等于0的,如果没有处于rehash的过程,该值是-1。每rehash完一个槽位,那么该值会自增。在rehash的过程中,如果trehashidx所指向的槽位没有值,那么会去递归地寻找下一个trehashidx指向槽位不空的槽位。

 

这就是redis哈希表实现上rehash的性能很高的原因。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis 是一个基于内存的高性能键值数据库,常被用于缓存、消息队列等场景。Redis 的底层实现原理主要包括以下几个方面: 1. 内存存储Redis 将所有数据都存储在内存中,通过使用数据结构来提高内存使用效率,如使用压缩列表来存储链表等。 2. 异步 I/O:Redis 采用单线程模型,通过异步 I/O 来提高并发处理能力。当客户端发送请求时,Redis 将请求放入请求队列中,然后通过 epoll 或 kqueue 等机制来监听文件描述符,当有请求完成时,再将结果返回给客户端。 3. 数据持久化:Redis 支持两种数据持久化方式,分别是快照和日志。快照是将内存中的数据定期保存到磁盘上,而日志则是将每个写操作转化为日志,当需要恢复数据时,通过重新执行日志中的写操作来实现。 4. 多种数据结构支持:Redis 支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等,每种数据结构都有不同的实现方式,如字符串采用简单动态字符串,哈希表采用哈希表等。 5. 网络协议:Redis 使用自定义的网络协议,协议格式简单,易于解析。客户端与 Redis 服务器之间的通信都是通过网络协议来实现的。 总之,Redis 的底层实现原理主要是通过内存存储、异步 I/O、数据持久化、多种数据结构支持和网络协议等多种技术手段来实现高性能和高可用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值