redis源码之hash结构的实现
redis的hash的基本命令暂时先不多说,我们直接步入正文 在redis的hash结构中,存在这样一种现象
127.0.0.1:6379> hset user:001 name john age 25 sex man
(integer) 3
127.0.0.1:6379> hgetall user:001
1) "name"
2) "john"
3) "age"
4) "25"
5) "sex"
6) "man"
我们先给user:001分别设置了name,age,sex属性,然后通过hgetall获取所有属性,这一切看起来还比较正常 但是接下来
127.0.0.1:6379> hset user:002 name john age 25 sex man extra xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(integer) 4
127.0.0.1:6379> hgetall user:002
1) "name"
2) "john"
3) "extra"
4) "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
5) "sex"
6) "man"
7) "age"
8) "25"
我们给user:002多设置了一个extra属性,并且设置的值比较大,然后用hgetall获取所有属性的时候发现返回的顺序不是按照我们设置的时候的属性的顺序了,这是为什么呢?
其实主要原因是:hash数据结构底层实现为一个字典(dict),也是redisDb用来存储k-v的数据结构,当数据量比较小,或者单个元素比较小的时候,底层用ziplist存储,数据大小和元素数量阈值可以通过如下参数设置
hash-max-ziplist-entries 512 //ziplist元素个数超过512,将改为hashtable编码 hash-max-ziplist-value 64 //单个元素大小超过64byte时,将改为hashtable编码 对于上面的例子,主要是因为单个元素大小超过了64byte,所以改为了hashtable编码,导致了hgetall获取属性的时候和设置的顺序不一样
压缩表的结构如图
其实很多同学也有一个疑问,hash和string类型到底有啥本质的区别?其实我们从源码可以看出来, 对于string类型来说,string类型是基于RedisDb的,如果string的数量不断的变多,就会导致dictht部分不断的rehash
而对于hash类型的来说,hash不存在dictht不断rehash的问题
但是其实也是各有利弊,比如hash就没法对某个key设置过期时间,而且redis中有一个很大的忌讳,就是不要让某个key过大,容易阻塞,所以个人还是更推荐string的方式
- 通过 wp-config.php 禁止安装、升级或编辑WordPress 主题与插件
- 利用VS2005中的Code Snippets提高开发效率
- 用schemaSpy制作数据库文档
- WordPress 投票插件Post Ratings,可在谷歌搜索显示星级投票(附中文包下载)
- Spark学习笔记——共享变量
- 如何升级Mono
- 使用信息架构视图访问数据库元数据
- Java 基础标识符
- 在Windows上玩转Mono/Linux
- Active Record和Domain Object + Dao
- 别再设计易碎的Web API
- 开放源代码与.NET应用程序平台的性能测试
- Mono Libgdiplus库
- es6 Symbol
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 第09期:有关 MySQL 字符集的乱码问题
- 机器人系统建模与辨识工具箱sympybotic
- 微服务聚合Swagger文档,这波操作是真的香!
- CEF-version2623完整编译教程
- Node 中如何引入一个模块及其细节
- PHP 错误和异常处理(下)
- PHP 错误和异常处理(上)
- 玩转 PhpStorm 系列(一):主题篇
- 如何用云开发打造“万人同屏”高并发实时互动小程序
- 实战丨云开发帮你和「火箭少女」合个影!
- 开源数据闪回工具—binlog2sql介绍
- 盘点前端面试常见的15个TS问题,你能答对吗?
- 『深度思考』对CenterNet的一些思考与质疑·测试对比CenterNet与U版YoloV3速度与精度
- 优秀员工应该具备的11个特质
- 腾讯位置服务教你快速实现距离测量小工具