概述
最近在思考一个问题,我们想判断redis
里存不存在一个预期值,有两种实现思路
- 判断型
exists(key)
或者null != redis.get(key)
- 预期型
"expectedValue".eqauls(redis.get(key))
第一种,就是说 redis
里可能不存在
这个值
第二种,redis
里这个key 肯定
对应一个 value,只不过可能不是我们预期的值
那么到底哪个效率高呢,
搜索了一番资料,整理发在这里
redis get 原理
redis 内存结构如下
typedef struct redisDb
{
dict *dict; /* The keyspace for this DB */
dict *expires; /* Timeout of keys with a timeout set */
dict *blocking_keys; /* Keys with clients waiting for data (BLPOP) */
dict *io_keys; /* Keys with clients waiting for VM I/O */
dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */
int id;
} redisDb;
redisDb 中 ,dict 成员是与实际存储数据相关的. dict 的定义如下:
typedef struct dict
{
dictType *type;
void *privdata;
dictht ht[2];
int rehashidx; /* rehashing not in progress if rehashidx == -1 */
int iterators; /* number of iterators currently running */
} dict;
typedef struct dictht
{
dictEntry **table;
unsigned long size;
unsigned long sizemask;
unsigned long used;
} dictht;
typedef struct dictEntry
{
void *key;
void *val;
struct dictEntry *next;
} dictEntry;
借用大佬画的图
image
我们看到 ht[0]
,可以理解成 java
里 HashMap
的数组
这个“数组” 存的是一个一个的 dictEntry
, 类似于 java
里 HashMap
的 Entry
,
dictEntry
存的是 key 指针(指向key)和 value 指针(指向value),还有链表的next
节点
其实分析下来结构和 java
的 HashMap
高度类似
结论
在 Java
里, HashMap
的get
逻辑是这样的:
传入key
算出key
的 hashcode
hashcode
和 数组长度做一个运算,得到 索引
取索引处的链表(java8里有可能是红黑树), 遍历比较得到 value
对于 redis
, 结合 脚本之家 这篇文章,
可以发现get
原理和 HashMap
的get
类似
所以:
命中
和 不命中
单次查询效率是一致的
当然了,对于redis整体的影响,我就不清楚了,还没有研究
网友评论