redis详解(持续更新)
Redis是一种key-value型数据库,运行于内存中,与它相似的数据库有memcached,现在基本被Redis替代。
Redis适用场景
我们要与传统的关系型数据库进行对比才能更好的了解与使用Redis
1.高并发场景, redis是个单线程的程序对于纯内存操作如hash查找可达到每秒百万次的数量级。
比如说点赞这个业务,我们在redis中可以这样用set(关于redis的数据结构下文会详述)来存,key就是被点赞实体(如问题或评论)的id或唯一标志,主动点赞的用户ID都存在这个set里面, 执行点赞时把用户ID存在这个set里面就行了。 我们再看看MySQL里怎么做,被点赞实体的ID和点赞实体的ID就是一条记录,第一点由于锁的存在读取点赞人数时会对表加读锁,这时候就不能添加记录,第二点是基于磁盘的,读写速率都很慢。
2.列举最新列表
redis中可使用list这个数据结构,用来存储最新的n条记录(lpush,和trim配合使用),每回取就使用lrange命令就行 。我们再看看MySQL在里面怎么做,如下是一个典型的查询语句:select * from table where.... order by time desc limit n ,随着数据增多只会越来越慢。
3.排行榜
redis提供一种数据结构sortset,优先队列即里面的元素可以按分值来排序。常用操作zadd等,由于这些信息也是常常跟新的基于磁盘的MySQL显然性能不够好。
4.消息队列,阻塞队列
redis提供阻塞队列这种数据数据结构常用,命令如brpop。
5.设置过期数据
redis,的K-V数据结构提供数据过期值,比如对于验证码,缓存(基于缓存计划会再写一篇详细的文章)
综上,在实际开发中我们常常是将MySQL和Redis一起结合来使用的,不同场景使用不同的工具。
Redis 常用数据结构及命令 双向列表List: lpush,lpop,brpop,lrange,linsert等等 无序集合Set: scard,sdiff(A中有B中没的),smembers,sinter(交集) 有序集合SortedSet: zadd,zscore 单一数值KV: set,setex 存储对象Hash: hset,hget
更多详细信息请见https://redis.io/commands
Redis部分数据结构的底层设计
1.动态字符串SDS
我们执行一个命令,set msg "hello" ,那么底层就是产生两个SDS对象。 接下来我们看看SDS与C语言的传统字符串有什么区别(Redis使用C语言来编写)。SDS实则是一个结构体:如下图
这个结构体有一个字节数组,当前字符长度,可以数组长度(free)组成,SDS主要在以下两方面做了优化
C语言若字符串溢出,那么系统将重新分配内存(这个可能执行系统调用)并将内容都复制到另一个数组当中,对于高性能的redis来说这是很耗时间的。SDS则在每一次拼接字符串时判断空间是否够大,不够分配1MB内存,够则分配free大小内存。 字符串缩短时内存先不回收,而是暂时存起来,减少内存重分配次数 二进制安全,使用len判断字符串是否结束,可保存二进制数据2.链表
双向无环链表3.字典
广泛用于redis各种功能,一个字典有两个哈希表,一个平时使用一个rehash时使用 hash冲突时一个索引上的多个键连接成一个单项列表(加在表头) 根据负载因子(内存与时间的平衡,已保存节点数/哈希表大小,临界值分别是0.1,5)决定是否rehash。采用渐进式rehash(保证性能,和写时复制技术思路相似),主要为以下几个步骤 为上面说的另一个hash h1表分配空间 字典内维持一个索引计数器,每次执行添加,删除,查找或更新时除指定操作后还将相应键值对rehash到h1上,直至操作完成(每个哈希表会标有已存在的实体数)Redis持久性
Redis提供两种持久化方式:快照(RDB),和AOF(记录每一个操作)
RDB每隔一个特定的时间保存那个时间点的一个数据快照 AOF保存每一个操作,Redis重启时逐条执行每个操作重建原来的数据 两种持久化方式可以同时存在,Redis重启时优先使用AOFRDB
原理
Redis调用Fork()创建子进程 子进程将数据写入到一个RDB文件里 替换旧的RDB文件 文件存放在当前目录的dump.rdb文件内,可以通过redis.conf修改文件名及目录
缺点
由于每隔一段时间执行,,可能会造成数据丢失。 使用Fork()创建子进程时,如果数据量很大Fork()造作会造成Redis暂停服务几秒钟。优点
RDB文件易于做备份,数据量大时启动速度快常见配件信息(redis.conf中)
AOF
优点
丢失数据的可能性减少缺点
AOF文件比RDB大
未完待续。。。
参考资料
https://www.zhihu.com/question/19764056
https://segmentfault.com/a/1190000002906345
http://blog.csdn.net/hguisu/article/details/8836819
上一篇: python timestamp和datetime之间转换详解
下一篇: Cookie--小知识总结