一、关于 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. Unity 游戏框架搭建 2019 (三十二、三十三) 类的命名 & 代码文件命名

    昨天我们完成了第八个示例的第二个 MenuItem 菜单顺序的调整. 我们今天再往下接着调整. 我们来看下接下来的 MenuItem 代码如下: [MenuItem("QFramework/ ...

  2. vue+element-ui中引入阿里播放器

    1.在public文件下的index.html文件中插入以下代码: <link rel="stylesheet" href="https://g.alicdn.co ...

  3. C/C++,被誉为“最经典的编程语言”,不仅是因为编程入门需要学?

    计算机诞生初期,用机器语言或汇编语言编写程序; 第一种高级语言FORTRAN诞生于1954年; BASIC语言(1964)是由FORTRAN语言的简化而成的是为初学者设计的小型高级语言; C语言是19 ...

  4. java学习(第三篇)String类

    一.创建一个字符串 1.String(char a[]):用一个字符数组a创建一个string类型 char a[]= {'h','e','l','l','o'}; String s=new Stri ...

  5. windows 查看被占用的端口信息

    如何查询 1.使用命令:netstat -aon|findstr "8080" 查询被占用的端口的进程 PID 2.使用命令:tasklist | findstr "15 ...

  6. for-loop 与 json.Unmarshal 性能分析概要

    原文地址:for-loop 与 json.Unmarshal 性能分析概要 前言 在项目中,常常会遇到循环交换赋值的数据处理场景,尤其是 RPC,数据交互格式要转为 Protobuf,赋值是无法避免的 ...

  7. dlopen failed: empty/missing DT_HASH in "libx.so" (built with --hash-style=gnu?)

    崩溃日志内容: java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH in "libxxxx.so&quo ...

  8. 数据库SQL语言从入门到精通--Part 3--SQL语言基础知识

    数据库从入门到精通合集(超详细,学习数据库必看) 一.关系 单一的数据结构----关系 现实世界的实体以及实体间的各种联系均用关系来表示 逻辑结构----二维表 从用户角度,关系模型中数据的逻辑结构是 ...

  9. 图论--SCC缩点--Tarjan

    // Tarjan算法求有向图强连通分量并缩点 /*强连通缩点与双连通缩点大同小异,也就是说将强连通分支缩成一个点之后,没有强连通,成为有向无环图,在对图进行题目的操作.*/ #include< ...

  10. LCA 学习总结

    怎么说,LCA裸题直接套板子,大家都会做,这样的题没必要看,剩下的题发先LCA只是一个工具就像是搜索一样,只是一个工具而不是一种算法,所以借助这套工具在其图论问题如最长路,数据结构等问题上再去发挥作用 ...