Redis
是支持多
key-value
数据库
(
表
)
的
,
并用
RedisDb
来表示一个
key-value
数据库
(
表
). redisServer
中有一个
redisDb *db;
成员变量
,
RedisServer
在初始化时
,
会根据配置文件的
db
数量来创建一个
redisDb
数组
.
客户端在连接后
,
通过
SELECT
指令来选择一个
reidsDb,
如果不指定
,
则缺省是
redisDb
数组的第
1
个
(
即下标是
0)redisDb.
一个客户端在选择
redisDb
后
,
其后续操作都是在此
redisDb
上进行的
.
dictType
中定义的为各种函数
:
哈希函数
,key
比较函数
,key/value
复制函数等
.
dict
是主要是由
struct
dictht
的哈希表构成的
,
之所以定义成长度为
2
的
(dictht ht[2])
哈希表数组
,
是因为
redis
采用增量的
rehash.
这种渐进的
rehash
需要一个额外的
struct dictht
结构来保存
.
dictht
中的
table
是一个数组
+
指针形式的
hash
表,
size
表
hash
数组
(
桶
)
的大小,
used
表示
hash
表的元素个数,这两个值与
rehash
、
resize
过程密切相关。
sizemask
等于
size-1
,这是为了方便将
hash
值映射到数组中。
iterators
记录当前
dict
中的迭代器数,主要是为了避免在有迭代器时
rehash
,在有迭代器时
rehash
可能会造成值的丢失或重复
.
rehashidx
表示上次
rehash
时在
ht[0]
的下标位置
.
关于
rehash:
1)原因:
redis使用的为动态大小的哈希表,当哈希表的大小不能满足需求,元素的hash碰撞比较多时进行扩容. 由于在数据结构中定义使用两个哈希表,当第一个表ht中的元素大于桶的个数时,进行扩容(dictAdd->_dictKeyIndex->_dictExpandIfNeeded->dictExpand),每次扩容大小为((d->ht[0].size > d->ht[0].used) ? d->ht[0].size : d->ht[0].used)*2,初始值为DICT_HT_INITIAL_SIZE = 4.扩容后开始将第一个表ht中的元素进行增量rehash到第二个表中,当rehash完成时,将第二个表赋给第一个表,并将原表内存释放.
/* Check if we already rehashed the whole table... */
if (d->ht[0].used == 0) {
zfree(d->ht[0].table);
d->ht[0] = d->ht[1];
_dictReset(&d->ht[1]);
d->rehashidx = -1;
return 0;
}
2)原则: 增量更新与分批更新同时进行,不阻塞请求. 将操作平摊到每次操作,以及充分利用server idle时的CPU资源,以减少突然的rehash行为造成服务器性能的瞬间下降.
3)模式:
lazy rehashing:在每次对dict进行操作的时候执行一个slot的rehash
_dictRehashStep中,也会调用dictRehash,而_dictRehashStep每次仅会rehash一个值从ht[0]到ht[1],但由于_dictRehashStep是被dictGetRandomKey、 dictFind、 dictGenericDelete、dictAdd调用的,因此在每次dict增删查改时都会被调用,这无疑就加快rehash了 过程。
active rehashing:每100ms里面使用1ms时间进行rehash。
serverCron中,当没有后台子线程时,会调用incrementallyRehash,最终调用dictRehashMilliseconds。 incrementallyRehash的时间较长,rehash的个数也比较多。这里每次执行 1 millisecond rehash 操作;如果未完成 rehash,会在下一个loop里面继续执行。
4)方法:
active rehashing: serverCron->incrementallyRehash->dictRehashMilliseconds->dictRehash(100)
lazy rehashing: dictAdd/dictGenericDelete/dictFind/dictGetRandomKey->_dictRehashStep-> dictRehash(1)
分享到:
相关推荐
Redis 是一个高性能的键值存储系统,广泛应用于缓存、消息队列、实时分析等场景。在 Python 中,可以通过多个客户端库与 Redis 进行交互,其中最流行的是 `redis-py`。以下是 Redis Python 客户端及其主要功能的描述...
Redis是一个开源的、内存中的数据结构存储系统,它可以用作数据库、缓存和消息代理。Redis支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等,并提供了丰富的API供开发者使用。 在Redis开发过程中,...
Redis是一个开源的、内存中的数据结构存储系统,它可以用作数据库、缓存和消息中介。它支持多种数据类型,包括字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(sorted set)等,并提供了丰富...
Redis通常用于缓存、消息队列、实时数据分析、计数器、排行榜等场景,Redis是一个功能强大的键值对存储数据库,具有高速、高可用、可扩展等特点,适用于各种应用场景。 它的主要特点包括: 速度快:Redis使用ANSI ...
Redis还具有多种应用场景,如在Web应用中存储会话信息、实现消息队列、排行榜和计数器、分布式锁以及实时分析等。例如,Redis的发布订阅功能可以用来实现消息队列,通过将消息发布到特定的频道,可以让订阅该频道的...
和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set 有序集合)和hash(哈希类型),数据存储如下图分析 为了分别为ID存入多个键值对,此次仅对Hash数据...
Redis支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等,使其非常灵活和强大。 Redis的特点包括: - 高性能:Redis数据存储在内存中,读写速度非常快。 - 支持持久化:Redis可以将数据持久化到磁盘,...
存储结构(物理结构):描述数据在计算机中如何具体存储。例如,数组的连续存储,链表的动态分配节点,树和图的邻接矩阵或邻接表表示等。 基本操作:针对每种数据结构,定义了一系列基本的操作,包括但不限于插入、...
数据结构服务器-简单地说,Redis是一个数据库,但与传统数据库不同,因为它直接公开了核心数据结构-字符串,列表,集合,哈希,排序集合,地理空间索引,超级日志,位图等。 使用可以添加新的数据结构和功能 其他...
Hash表采用了数组加链表的结构,即一个数组元组中不再是存储单个元素,而是存储一个链表,就好比包租婆收租的时候,一个握把上面挂了一连串的钥匙一样。Hash表的引出是为了减少查询数据库操作所带来的时间问题,将...
3.1.4 Redis数据存储与访问 43 3.1.5 Redis数据查询 47 3.1.6 HBase数据存储与访问 50 3.1.7 HBase数据查询 52 3.1.8 Apache Cassandra数据存储与访问 54 3.1.9 Apache Cassandra数据查询 55 3.2 NoSQL数据...
支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型) 答案解析:使用开源C语言编写 10. 以下哪个不属于Redis三大架构 [单选题] A.主从复制...
│ Java面试题78:redis存储对象的方式.mp4 │ Java面试题79:redis数据淘汰机制.mp4 │ Java面试题80:java访问redis级redis集群?.mp4 │ Java面试题81:微信公众号分类和微信开发原理.mp4 │ Java面试题82:怎么...
12.2.2 HttpClient连接池源码分析 240 12.2.3 HttpClient 4.2.3配置 241 12.2.4 问题示例 243 12.3 线程池 244 12.3.1 Java线程池 245 12.3.2 Tomcat线程池配置 248 13 异步并发实战 250 13.1 同步阻塞调用 251 13.2...
可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...
可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...
可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...
可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...
可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL...