关于redis,你需要了解的几点!
一、关于 redis key:
1、是二进制安全的,也就是说,你可以使用任何形式的二进制序列来作为key,比如一个string,或者一个jpg图片的数据,需要说明的是,空字符串也是一个有效的key。
2、不建议使用过长的key,影响内存占用及数据查性能,对于过长的key,可以通过hash(例如SHA1)处理转换。
3、建议使用有意义及统一格式的key。
4、最大允许key大小为512M。
二、String 类型应用:
1、作为原子计数器:incr、decr、incrby
2、结合append命令,作为基于时间的增量序列。
3、随机访问及获取值区域,getrange、setrange。
附:需要注意的是append及range操作容易引起内存浪费和碎片化问题。
三、hash 类型:ziplist or hashtable
1、单个hash最多支持232 - 1个键值对。
2、关于hash类型的内部编码:ziplist(压缩列表) & hashtable(哈希表)
配置:hash-max-ziplist-entries(hash类型最大kv数据,默认512)、hash-max-ziplist-value(单个v值最大值, 默认64)
redis 采用何种结构取决于hash中元素数及元素值得大小,当同时满足小于配置时,redis使用ziplist编码存储,否则会转化为hashtable。
ziplist编码使用更加紧凑的结构实现多个元素的连续存储,因此占用的内存更小。
当数据类型无法满足配置条件,此时使用ziplist编码存储读写效率会下降,所以转换使用hashtable编码存储(O(1)时间复杂度)。
示例:添加 testuser hash类型key,先后设置元素name、desc不同长度元素值,分别查看内部编码类型

四、关于redis存储:redisObject

redis 对象内部存储形态。
1、type:数据类型、例如sting、hash、list、set、zset等,值类型查看命令【type】。
2、encoding:值存储内部实现的数据结构,具体可以参考第七部分。
3、lru:最后一次被访问时间,辅助回收,可以通过 object idletime {key} 在不更新lru属性情况下查看key的空闲时间。
4、refcount:当前对象被引用次数,辅助回收,可以通过 object refcount {key} 查看引用数,当对象为整数且值在范围在[0-9999]时,redis可以通过共享对象的方式来节省内存。
目前共享对象池只对整数设置了0~9999个共享对象,一方面整数对象池复用率最大,同时等值判断上时间复杂度为O(1)。
5、*ptr:数据存储或指向,数据本身或者指向数据的指针,redis3.0之后,长度在39以内的字符串数据,内部编码为embstr,内存创建时,字符串和redisObject一起分配,减少一次内存分配。
五、关于SDS
simple dynamic string:redis内部自定义简单动态字符串结构。

1、字符串属性的O(1)时间复杂度获取。
2、空间与分配、减少内存再分配。
3、惰性删除机制,字符串缩减后空间不释放,作为预分配空间保留。
六、关于对象属性存储:json or hash
对象属性存储可以通过整体json存储或者hash kv存储。具体应用选择,可以结合整体对象大小及属性操作需求来决定。
对于频繁整体操作,且对象数据量较小的一般采用json字符串类型存储。
对于多对象属性层级操作情景,可能hash会比较合适。
七、关于存储编码

如上图,同一种数据类型,可以有多种不同内部编码存储形式。具体redis采用那种编码形式与实际应用的数据值类型相关,如上述第三部分论述hash类型的编码转换。
数据的编码类型在数据写入的时候确定,不可变换,且只能向大内存编码行使转换。
如下,重新设置 testuser desc值,testuser对象的编码形式保持不变:

编码转换时机:

八、关于ziplist
通过第七节,我们可以看到hash、list、zset底层都有应用这种存储结构。
基本特点:
1、连续性内存存储。
2、可以模拟双向链表,O(1)时间复杂度内出入队操作。
3、读写性能跟数据的元素个数及值长度相关,适合存储小对象和长度有限的数据。
4、数据增删涉及复杂的内存操作。
ziplist基本结构:

1、zlbytes:int32类型、4字节,ziplist整体字节长度。
2、zltail:int32类型、4字节,记录距离尾节点偏移量,用于尾节点弹出。
3、zllen:int16类型,2字节,ziplist节点数量。
4、entry:数据节点,长度不定。
entry 即链表node,内部结构包含:
prev_entry_bytes_length:前一个节点所占用的空间,用户快速定位。
encoding:当前数据节点编码类型及长度,前两位标识编码类型,其余标识数据长度。
contents:节点数据值。
5、zlend:1字节,记录列表结尾。
九、关于redis内存消耗
redis内存消耗包括自身内存,键值对象占用、缓冲区内存占用及内存碎片占用。
1、缓冲区内存:包括客户端缓存、复制及压缓冲区及AOF缓冲区。
2、内存碎片:固定范围内存块儿分配。
redis默认使用jemalloc内存分配器,其它包括glibc、tcmalloc。
内存分配器会首先将可管理的内存分配为规定不同大小的内存块以备不同的数据存储需求,但是,我们知道实际应用中需要存储的数据大小不一,规范不一,内存分配器只能选择最接近数据需求大小的内存块儿进行分配,这样就伴随着“占不满”空间的碎片浪费。
jemalloc针对内存碎片有相应的优化策略,正常碎片率为mem_fragmentation_ratio在1.03左右。
第二部分我们说过,对string值得频繁append及range操作会会导致内存碎片问题,另外,第七部分,SDS惰性内存回收也会导致内存碎片,同时过期键内存回收也伴随着所释放空间的无法充分利用,导致内存碎片率上升的问题。
碎片处理:
应用层面:尽量避免差异化的键值使用,做好数据对齐。
redis服务层面:可以通过重启服务,进行碎片整理。
3、maxmemory及maxmemory-policy控制redis最大可用内存及内存回收。需要注意的是内存回收执行影响redis的性能,避免频繁的内存回收开销。
关于redis,你需要了解的几点!的更多相关文章
- 使用redis构建可靠分布式锁
关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...
- Ignite性能测试以及对redis的对比
测试方法 为了对Ignite做一个基本了解,做了一个性能测试,测试方法也比较简单主要是针对client模式,因为这种方法和使用redis的方式特别像.测试方法很简单主要是下面几点: 不作参数优化,默认 ...
- mac osx 安装redis扩展
1 php -v查看php版本 2 brew search php|grep redis 搜索对应的redis ps:如果没有brew 就根据http://brew.sh安装 3 brew ins ...
- Redis/HBase/Tair比较
KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式 支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...
- Redis数据库
Redis是k-v型数据库的典范,设计思想及数据结构实现都值得学习. 1.数据类型 value支持五种数据类型:1.字符串(strings)2.字符串列表(lists)3.字符串集合(sets)4.有 ...
- redis 学习笔记(2)
redis-cluster 简介 redis-cluster是一个分布式.容错的redis实现,redis-cluster通过将各个单独的redis实例通过特定的协议连接到一起实现了分布式.集群化的目 ...
- redis 学习笔记(1)
redis持久化 snapshot数据快照(rdb) 这是一种定时将redis内存中的数据写入磁盘文件的一种方案,这样保留这一时刻redis中的数据镜像,用于意外回滚.redis的snapshot的格 ...
- python+uwsgi导致redis无法长链接引起性能下降问题记录
今天在部署python代码到预生产环境时,web站老是出现redis链接未初始化,无法连接到服务的提示,比对了一下开发环境与测试环境代码,完全一致,然后就是查看各种日志,排查了半天也没有查明是什么原因 ...
- nginx+iis+redis+Task.MainForm构建分布式架构 之 (redis存储分布式共享的session及共享session运作流程)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,上一篇分享文章制作是在windows上使用的nginx,一般正式发布的时候是在linux来配 ...
- windows+nginx+iis+redis+Task.MainForm构建分布式架构 之 (nginx+iis构建服务集群)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,由标题就能看出此内容不是一篇分享文章能说完的,所以我打算分几篇分享文章来讲解,一步一步实现分 ...
随机推荐
- Laravel - 基础
1.使用 composer 创建项目 composer create-project --prefer-dist laravel/laravel blog 报错1 [ErrorException]pr ...
- pytorch LSTM情感分类全部代码
先运行main.py进行文本序列化,再train.py模型训练 dataset.py from torch.utils.data import DataLoader,Dataset import to ...
- c++指定输出小数的精度
在c++中,有的时候要对输出的double型或float型保留几位小数,这时可以使用setflags(ios::fixed),不过要先包含有文件<iomainp>,具体如下 例: #inc ...
- 1、flink介绍,反压原理
一.flink介绍 Apache Flink是一个分布式大数据处理引擎,可对有界数据流和无界数据流进行有状态计算. 可部署在各种集群环境,对各种大小的数据规模进行快速计算. 1.1.有界数据流和无界 ...
- PHP--关于上传文件大小的问题
参考:https://www.cnblogs.com/jianqingwang/p/5863960.html https://blog.csdn.net/u013168253/article/deta ...
- android位运算简单讲解
一.前言 在查看源码中,经常会看到很多这样的符号“&”.“|”.“-”,咋一看挺高大上:仔细一看,有点懵:再看看,其实就是大学学过的再普通不过的与.或.非.今天小盆友就以简单的形式分享下,同时 ...
- CSRF与平行越权的区别
.CSRF攻击者不需要登录,越权攻击者也得登录,只是没有做针对性的控制: .CSRF攻击者自己不访问受攻击页面,诱导受害者在登录被攻击系统后点击攻击页面:越权攻击者可以直接访问受攻击页面: .CSRF ...
- 【JAVA基础】04 Java语言基础:方法
1. 方法概述和格式说明 为什么要有方法 提高代码的复用性 什么是方法 完成特定功能的代码块. 方法的格式 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2...) { 方法 ...
- 汉字编码对照表(gb2312/Big5/GB2312)
一.汉字编码的种类 1.GB2312又称国标码,由国家标准总局发布,1981年5月1日实施,通行于大陆.新加坡等地也使用此编码.它是一个简化字的编码规范,当然也包括其他的符号.字母.日文假名等,共74 ...
- 15个Nodejs应用场景
15个Nodejs应用场景 我们已经对Nodejs有了初步的了解,接下来看看Nodejs的应用场景. 2.1 Web开发:Express + EJS + Mongoose/MySQL express ...