redis数据库查找key在内存中的位置的方法_数据库其它

一、预先需要了解的知识
1、redis 中的每一个数据库,都由一个 redisDb 的结构存储。其中,redisDb.id 存储着 redis 数据库以整数表示的号码。redisDb.dict 存储着该库所有的键值对数据。redisDb.expires 保存着每一个键的过期时间。
2、当redis 服务器初始化时,会预先分配 16 个数据库(该数量可以通过配置文件配置),所有数据库保存到结构 redisServer 的一个成员 redisServer.db 数组中。当我们选择数据库 select number  时,程序直接通过 redisServer.db[number] 来切换数据库。有时候当程序需要知道自己是在哪个数据库时,直接读取 redisDb.id 即可。
3、既然我们知道一个数据库的所有键值都存储在redisDb.dict中,那么我们要知道如果找到key的位置,就有必要了解一下dict 的结构了:

复制代码 代码如下:

typedef struct dict {

// 特定于类型的处理函数
dictType *type;

// 类型处理函数的私有数据
void *privdata;

// 哈希表(2个)
dictht ht[2];

// 记录 rehash 进度的标志,值为-1 表示 rehash 未进行
int rehashidx;

// 当前正在运作的安全迭代器数量
int iterators;
} dict;

由上述的结构可以看出,redis 的字典使用哈希表作为其底层实现。dict 类型使用的两个指向哈希表的指针,其中 0 号哈希表(ht[0])主要用于存储数据库的所有键值,而1号哈希表主要用于程序对 0 号哈希表进行 rehash 时使用,rehash 一般是在添加新值时会触发,这里不做过多的赘述。所以redis 中查找一个key,其实就是对进行该dict 结构中的 ht[0] 进行查找操作。
4、既然是哈希,那么我们知道就会有哈希碰撞,那么当多个键哈希之后为同一个值怎么办呢?redis采取链表的方式来存储多个哈希碰撞的键。也就是说,当根据key的哈希值找到该列表后,如果列表的长度大于1,那么我们需要遍历该链表来找到我们所查找的key。当然,一般情况下链表长度都为是1,所以时间复杂度可看作o(1)。
二、当redis 拿到一个key 时,如果找到该key的位置。
了解了上述知识之后,我们就可以来分析redis如果在内存找到一个key了。
1、当拿到一个key后, redis 先判断当前库的0号哈希表是否为空,即:if (dict->ht[0].size == 0)。如果为true直接返回NULL。
2、判断该0号哈希表是否需要rehash,因为如果在进行rehash,那么两个表中者有可能存储该key。如果正在进行rehash,将调用一次_dictRehashStep方法,_dictRehashStep 用于对数据库字典、以及哈希键的字典进行被动 rehash,这里不作赘述。
3、计算哈希表,根据当前字典与key进行哈希值的计算。
4、根据哈希值与当前字典计算哈希表的索引值。
5、根据索引值在哈希表中取出链表,遍历该链表找到key的位置。一般情况,该链表长度为1。
6、当 ht[0] 查找完了之后,再进行了次rehash判断,如果未在rehashing,则直接结束,否则对ht[1]重复345步骤。
到此我们就找到了key在内存的中位置了。

时间: 2024-10-13 21:48:49

redis数据库查找key在内存中的位置的方法_数据库其它的相关文章

用SQL Server访问Sybase中的表的方法_数据库其它

问:SQL Server应该怎样访问Sybase数据库的表?  答:具体方法如下:  1: 安装Sybase客户端  版本的要求:  Sybase Client 11.9.2 for NT  1.1:安装完成后,运行开始->程序->Sybase->Dsedit  1.2:选择菜单的'Server Object',-> 'Add' 输入服务名 比如 1.70  1.3:然后在Server列表中选择'1.70',双击右边的对话框server address栏,在Network Addr

Android手机内存中文件的读写方法小结

  Android手机内存中文件的读写方法小结         这篇文章主要介绍了Android手机内存中文件的读写方法,实例总结了Android针对文件读写操作的相关技巧,非常具有实用价值,需要的朋友可以参考: 如何对手机内存中的文件数据进行读写呢? Context提供了领个方法来打开该应用程序的数据文件夹中的文件I/O流,具体如下: ? 1 FileInputStream openFileInput(String name) 打开应用程序的数据文件夹下的name文件对应的数据流 ? 1 Fi

未在本地计算机上注册“Microsoft.Jet.OleDb.4.0”提供程序错误的解决方法_数据库其它

最近在做一个导入Excel数据到数据库的程序出现了如下错误: 计算机上注册Microsoft.Jet.OleDb.4.0提供程序错误的解决方法_数据库其它-microsoft.jet.oledb"> 运行环境 数据库:SqlServer2008 R2 OS:Windows Server 2008 R2 IIS:IIS7 解决方法 在应用程序对用的应用程序池的高级设置中设置"启用32位应用程序"为"True"

在Win8系统下清除文件资源管理器中常用位置的方法

在Win8系统下清除文件资源管理器中常用位置的方法: 在Win8的文件资源管理器中,我们单击"文件",可以在右侧看到一个"常用位置"的列表.我们可以在其中找到我们经常访问的位置,方便我们的访问.如果你不希望其它用户在访问你的电脑时看到这些位置信息,我们可以将该列表清空. 具体操作方法如下: 首先打开文件资源管理器, 需要注意的是,"删除历史记录"中的两个选项无法对"常用位置"信息造成任何改变. 我们需要的是,在任务栏,单击右键

hadoop map-reduce中的文件并发操作_数据库其它

这样的操作在map端或者reduce端均可.下面以一个实际业务场景中的例子来简要说明. 问题简要描述: 假如reduce输入的key是Text(String),value是BytesWritable(byte[]),不同key的种类为100万个,value的大小平均为30k左右,每个key大概对应 100个value,要求对每一个key建立两个文件,一个用来不断添加value中的二进制数据,一个用来记录各个value在文件中的位置索引.(大量的小文件会影响HDFS的性能,所以最好对这些小文件进行

数据库设计的折衷方法_数据库其它

作项目分析,数据库设计是一个很重要也很难的问题, 完全按照范式有可能不符合用户需求,不利于编程, 看来是具体问题具体分析,数据库设计是范式和需求的折中. 在上学时,没觉得数据类型有多重要,现在发觉了解数据类型 的具体内容也是很重要的,可以知道不同数据库之间的兼容问题 该怎么处理. 数据库设计技巧: 第2 部分- 设计表和字段 1. 检查各种变化 我在设计数据库的时候会考虑到哪些数据字段将来可能会发生变更.比方说,姓氏就是如此(注 意是西方人的姓氏,比如女性结婚后从夫姓等).所以,在建立系统存储客

数据库分页查询方法_数据库其它

可能会有人说这些网上都有,但我的主要目的是把这些知识通过我实际的应用总结归纳一下,以方便大家查询使用. 下面就分别给大家介绍.讲解一下三种数据库实现分页查询的方法. 一. MySQL 数据库分页查询 MySQL数据库实现分页比较简单,提供了LIMIT函数.一般只需要直接写到sql语句后面就行了. LIMIT子句可以用来限制由SELECT语句返回过来的数据数量,它有一个或两个参数,如果给出两个参数, 第一个参数指定返回的第一行在所有数据中的位置,从0开始(注意不是1),第二个参数指定最多返回行数.

Access转成SQL数据库的方法_数据库其它

首先,我说的是在ACCESS2000,SQL2000之间转换,其他的我也还没有尝试过,希望大家多多试验,肯定是有办法的. 转换的方法 1.打开"控制面板"下"管理工具"中的"数据库源". 2.按"添加"添加一个新的数据源,在选择栏里选"Driver do microsoft Access (*.mdb)",完成后将出现一个框,在"数据库源"里面输入你想写的名称,我取名叫"ABC

卡巴斯基(AVP)内存驻留型病毒检测方法_漏洞研究

author:killer  <killer②uid0.net>     卡巴斯基反病毒软件(Kaspersky Antivirus),以前叫AntiViral Toolkit Pro(AVP),出于习惯和简单,这里一律称为AVP或KAV.     学习AVP的检测办法的意义一方面在于AVP的检测方法是经过理论验证和实践考验的科学合理的方法,另外DOS年代过来的朋友对于反病毒有过这样的经验:"机子感染病毒了?好,请用干净无毒的系统盘启动,然后全盘查杀.",我记得CIH横行那