关于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组建分布式架构,由标题就能看出此内容不是一篇分享文章能说完的,所以我打算分几篇分享文章来讲解,一步一步实现分 ...
随机推荐
- linq 高集成化数据访问技术
一: 新建名为linq的项目 创建 linq 1 在项目里添加文件夹 App_Code; 2 在文件夹(App_Code) 添加 名为db的 Linq To Sql 类 :一个Linq T ...
- Os-Hax: 1 靶机记录
靶机地址:172.16.1.197 Kali地址:172.16.1.108 1 信息搜集 靶机首页 相关信息查看 端口扫描: 开放22和80 目录扫描: 访问http://172.16.1.197/c ...
- 刷题记录:[V&N2020 公开赛]TimeTravel
题目复现链接:https://buuoj.cn/challenges 参考链接:2020 年 V&N 内部考核赛 WriteUp V&N公开赛2020 writeup httpoxy ...
- 用Python打造电脑人脸屏幕解锁神器附带接头暗号!
前言 最近突然有个奇妙的想法,就是当我对着电脑屏幕的时候,电脑会先识别屏幕上的人脸是否是本人,如果识别是本人的话需要回答电脑说的暗语,答对了才会解锁并且有三次机会.如果都没答对就会发送邮件给我,通知有 ...
- 每天都在用,但你知道 Tomcat 的线程池有多努力吗?
这是why的第 45 篇原创文章.说点不一样的线程池执行策略和线程拒绝策略,探讨怎么让线程池先用完最大线程池再把任务放到队列中. 荒腔走板 大家好,我是 why,一个四川程序猿,成都好男人. 先是本号 ...
- Apache Hudi集成Apache Zeppelin实战
1. 简介 Apache Zeppelin 是一个提供交互数据分析且基于Web的笔记本.方便你做出可数据驱动的.可交互且可协作的精美文档,并且支持多种语言,包括 Scala(使用 Apache Spa ...
- Kylin on Parquet 介绍和快速上手
Apache Kylin on Apache HBase 方案经过长时间的发展已经比较成熟,但是存在着一定的局限性.Kylin 查询节点当前主要的计算是在单机节点完成的,存在单点问题.而且由于 HBa ...
- springboot+dubbo简单分布式RPC调用demo
使用springboot+dubbo搭建RPC入门案例 本文背景简述: 最近在学习公司的一套RPC框架,初步接触的时候感觉挺复杂的.但是知道其原理肯定是和dubbo很相似的,毕竟都是RPC框架嘛,只是 ...
- 深入理解TCP建立和关闭连接
建立连接: 理解:窗口和滑动窗口TCP的流量控制TCP使用窗口机制进行流量控制什么是窗口?连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端 接收方发送的确认信息中包含了自 ...
- java并发中CountDownLatch的使用
文章目录 主线程等待子线程全都结束之后再开始运行 等待所有线程都准备好再一起执行 停止CountdownLatch的await java并发中CountDownLatch的使用 在java并发中,控制 ...