一、关于 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,你需要了解的几点!的更多相关文章

  1. 使用redis构建可靠分布式锁

    关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...

  2. Ignite性能测试以及对redis的对比

    测试方法 为了对Ignite做一个基本了解,做了一个性能测试,测试方法也比较简单主要是针对client模式,因为这种方法和使用redis的方式特别像.测试方法很简单主要是下面几点: 不作参数优化,默认 ...

  3. mac osx 安装redis扩展

    1 php -v查看php版本 2 brew search php|grep redis 搜索对应的redis   ps:如果没有brew 就根据http://brew.sh安装 3 brew ins ...

  4. Redis/HBase/Tair比较

    KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式    支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...

  5. Redis数据库

    Redis是k-v型数据库的典范,设计思想及数据结构实现都值得学习. 1.数据类型 value支持五种数据类型:1.字符串(strings)2.字符串列表(lists)3.字符串集合(sets)4.有 ...

  6. redis 学习笔记(2)

    redis-cluster 简介 redis-cluster是一个分布式.容错的redis实现,redis-cluster通过将各个单独的redis实例通过特定的协议连接到一起实现了分布式.集群化的目 ...

  7. redis 学习笔记(1)

    redis持久化 snapshot数据快照(rdb) 这是一种定时将redis内存中的数据写入磁盘文件的一种方案,这样保留这一时刻redis中的数据镜像,用于意外回滚.redis的snapshot的格 ...

  8. python+uwsgi导致redis无法长链接引起性能下降问题记录

    今天在部署python代码到预生产环境时,web站老是出现redis链接未初始化,无法连接到服务的提示,比对了一下开发环境与测试环境代码,完全一致,然后就是查看各种日志,排查了半天也没有查明是什么原因 ...

  9. nginx+iis+redis+Task.MainForm构建分布式架构 之 (redis存储分布式共享的session及共享session运作流程)

    本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,上一篇分享文章制作是在windows上使用的nginx,一般正式发布的时候是在linux来配 ...

  10. windows+nginx+iis+redis+Task.MainForm构建分布式架构 之 (nginx+iis构建服务集群)

    本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,由标题就能看出此内容不是一篇分享文章能说完的,所以我打算分几篇分享文章来讲解,一步一步实现分 ...

随机推荐

  1. vue2.x学习笔记(十一)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12586416.html. 表单的输入绑定 表单的输入绑定是一块很重要的内容,因为所有的业务系统都离不开基础表单的录 ...

  2. Java中的方法是什么以及方法的书写格式

    方法:完成特定功能的代码块注意:在很多语言里面有函数的定义,而在Java中函数被称为方法.方法格式:修饰符 返回值类型+ 方法名 (参数类型 参数名1,参数类型 参数名2...){方法体语句;retu ...

  3. 0day学习笔记(3)--修改函数返回地址

    环境: devc++(编译改为32位),windows10 源码(来自书中) #include <stdio.h> #define PASSWORD "1234567" ...

  4. 打印js对象内容

    function writeObj(obj){ var description = ""; for(var i in obj){ var property=obj[i]; desc ...

  5. qt 怎么让程序自带字体,就是说在操作系统上没有的字体

    字体要加到.qrc文件中 QString Widget::loadFontFamilyFromTTF() { static QString font; static bool loaded = fal ...

  6. Lambda表达式最佳实践

    简介 Lambda表达式java 8引入的函数式编程框架.之前的文章中我们也讲过Lambda表达式的基本用法. 本文将会在之前的文章基础上更加详细的讲解Lambda表达式在实际应用中的最佳实践经验. ...

  7. java并发中的Synchronized关键词

    文章目录 为什么要同步 Synchronized关键词 Synchronized Instance Methods Synchronized Static Methods Synchronized B ...

  8. 在独立的 Root 和 Home 硬盘驱动器上安装 Ubuntu

    安装 Linux 系统时,可以有两种不同的方式.第一种方式是在一个超快的固态硬盘上进行安装,这样可以保证迅速开机和高速访问数据.第二种方式是在一个较慢但很强大的普通硬盘驱动器上安装,这样的硬盘转速快并 ...

  9. Android 项目 Android 学习手册(一)

    前言: 当每次查询android 知识的时候,内心是凌乱的,总觉得要是有一个工具多好, 尤其在手机端如何可以查询的话,会非常完美,能大大减少选择查询的时间, 之前见了很多java 学习手册,把一些重要 ...

  10. springBoot(6):web开发-模板引擎jsp

    一.新建工程 注意新建的工程下没有webapp目录eclipse下会自动创建webapp目录这里我们需要自动创建一个webapp目录并创建WEB-INF. 对ServletInitializer.ja ...