今天闲暇时跟朋友聊起关于redis的几种模式和数据一致性的算法,今天从redis的几种数据结构开始给大家用几篇文章的时间聊一下我的一些见解。
首先围绕redis的8大特性对redis做一些剖析;
一、速度快。
为什么速度快,首先它是将数据存放内存中的,内存的读取速度会大量减少硬盘中的扫描、寻道时间,并且Redis是单线程的,线程在内存中是效率最高;redis也是使用C编写,不同于memcached使用java编写,不仅需要jvm的管理,而且在速度方面也是逊于C的内存管理。
二、持久化。
Redis的持久化可以保证将内存中的数据每隔一段时间就保存在磁盘中,重启的时候会重新加载到内存中。方式有RDB和AOF。RDB通俗的说类似于一个定时备份,缺点很明显就是不够实时,而AOP则是将所有操作记录记录下来,缺点就是备份的文件较大,当然也可以通过配置相应的重写机制去对数据进行定期的覆盖。
三、支持多种数据结构
- String
- Hash
- List
- Set
- Sorted set
我简单说一下常用的几个吧:
STRING自然就是一个典型的key、value结构,你可进行get、set、incr、decr等操作
HASH我们来看下Hash的应用场景,比如我们要存储一个用户信息对象数据,包含以下信息:
用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,如果用普通的key/value结构来存储,可能会有以下2种存储方式:
![d1d9d606d451931dc46ce5eb7bfe4d5e.png](https://i-blog.csdnimg.cn/blog_migrate/5b3a44cf1f1fbb7e83c79133f21a42c7.jpeg)
第一种方式将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,当要对它进行修改的时候需要将整个对象取回,在进行相应的序列化和反序列化,并且在此操作期间要处理好并发的处理
![afb2d0c060901bb7e6a2fffb794d00e4.png](https://i-blog.csdnimg.cn/blog_migrate/2e8f32b704d35e7c87ddf7bf0ad80306.jpeg)
第二种方法是这个用户信息对象有多少成员就存成多少个key-value对儿,用用户ID+对应属性的名称作为唯一标识来取得对应属性的值,但是很明显内存浪费很严重
那么Redis提供的Hash很好的解决了这个问题,Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口,如下图:
![a349fb97078866b77fabff507e2b657a.png](https://i-blog.csdnimg.cn/blog_migrate/0d6c73158d10eaa3d76db34450856792.jpeg)
也就是说,Key仍然是用户ID, value是一个Map,这个Map的key是成员的属性名,value是属性值,这样对数据的修改和存取都可以直接通过其内部Map的Key(Redis里称内部Map的key为field), 也就是通过 key(用户ID) + field(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。很好的解决了问题。
LIST 本身为一个双向链表,也就是说list既可以做栈、也可以做队列,比较常用的就是消息队列啦。
四、支持多种编程语言
支持Java、PHP、Python等众多编程语言。
五、功能丰富
如发布订阅、Lua脚本、事物、Pipeline(管道,即当指令到达一定数量后,客户端才会执行)。
六、简单
不依赖外部库、单线程、只有23000行的Code。
七、主从复制
八、高可用和分布式
关于第七和第八点我将在下一篇中对Redis哨兵、复制、集群的设计原理,以及区别,并且简单聊一下redis的数据一致性;