Redis用途
1.缓存
Redis提供了键值过期时间设置, 并且也提供了灵活控制最大内存和内存溢出后的淘汰策略。 可以这么说, 一个合理的缓存设计能够为一个网站的稳定保驾护航。
2.排行榜系统
Redis提供了列表和有序集合数据结构, 合理地使用这些数据结构可以很方便地构建各种排行榜系统。
3.计数器应用
Redis适用于高并发的递增、递减功能
递增指令:incr(默认从0开始)
递减指令:decr(默认从0开始,递减会出现负数,这点跟memcache不一样,mc到0)
4.社交网络
赞/踩、 粉丝、 共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适合保存这种类型的数据,
Redis提供的数据结构可以相对比较容易地实现这些功能。
5.消息队列系统
Redis提供了发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够足够强大, 但是对于一般的消息队列功能基本可以满足。
6.共享Session
7.限速
但是为了短信接口不被频繁访问, 会限制用户每分钟获取验证码的频率, 例如一分钟不能超过5次。
一些网站限制一个IP地址不能在一秒钟之内访问超过n次也可以采用类似的思路。
API的理解和使用
Redis发展历程中提供了move、 dump+restore、 migrate三组迁移键的方法。
Redis默认配置中是有16个数据库,推荐使用0号数据库?
假设databases=16, select0操作将切换到第一个数据库, select15选择最后一个数据库, 但是0号数据库和15号数据库之间的数据没有任何关联, 甚至可以存在相同的键。
Redis3.0中已经逐渐弱化这个功能, 例如Redis的分布式实现Redis Cluster只允许使用0号数据库, 只不过为了向下兼容老版本的数据库功能,该功能没有完全废弃掉。
Redis是单线程的。 如果使用多个数据库, 那么这些数据库仍然是使用一个CPU, 彼此之间还是会受到影响的。
多数据库的使用方式, 会让调试和运维不同业务的数据库变的困难,假如有一个慢查询存在, 依然会影响其他数据库, 这样会使得别的业务方定位问题非常的困难。
部分Redis的客户端根本就不支持这种方式。 即使支持, 在开发的时候来回切换数字形式的数据库, 很容易弄乱。
笔者建议如果要使用多个数据库功能, 完全可以在一台机器上部署多个Redis实例, 彼此用端口来做区分, 因为现代计算机或者服务器通常是有多个CPU的。
这样既保证了业务之间不会受到影响,又合理地使用了CPU资源。
scan命令可以解决keys命令可能带来的阻塞问题, 同时Redis还提供了hscan、 sscan、 zscan渐进式地遍历hash、 set、 zset。
小功能大用处
Redis提供了简单的事务, 之所以说它简单, 主要是因为它不支持事务中的回滚特性。
客户端
持久化
Redis提供了两种持久化方式: RDB和AOF。
RDB持久化是把当前进程数据生成快照保存到硬盘的过程, 触发RDB持久化过程分为手动触发和自动触发。
手动触发分别对应save和bgsave命令:save命令: 阻塞当前Redis服务器, 直到RDB过程完成为止, 对于内存比较大的实例会造成长时间阻塞, 线上环境不建议使用。
bgsave命令: Redis进程执行fork操作创建子进程, RDB持久化过程由子进程负责, 完成后自动结束。 阻塞只发生在fork阶段, 一般时间很短。
显然bgsave命令是针对save阻塞问题做的优化。 因此Redis内部所有的涉及RDB的操作都采用bgsave的方式, 而save命令已经废弃。
针对RDB不适合实时持久化的问题, Redis提供了AOF持久化方式来解决。
AOF( append only file) 持久化: 以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。
AOF的主要作用是解决了数据持久化的实时性, 目前已经是Redis持久化的主流方式。
开启AOF功能需要设置配置: appendonly yes, 默认不开启。
Redis单线程架构导致无法充分利用CPU多核特性, 通常的做法是在一台机器上部署多个Redis实例。
复制
拓扑
Redis的噩梦: 阻塞
内存
哨兵
集群
Redis Cluster是Redis的分布式解决方案, 在3.0版本正式推出, 有效地解决了Redis分布式方面的需求。 当遇到单机内存、 并发、 流量等瓶颈时, 可以采用Cluster架构方案达到负载均衡的目的。
1.节点取余分区
2.一致性哈希分区
3.虚拟槽分区
缓存设计
缓存穿透
缓存穿透是指查询一个根本不存在的数据, 缓存层和存储层都不会命中。(攻击者利用大量不存在的验证ID进行请求,导致了缓存穿透,引起后端数据库压力骤增而崩溃。)
有效地解决缓存穿透
有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,
一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法(我们采用的就是这种),
如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
雪崩优化
Redis监控运维云平台CacheCloud
其他
批量操作命令可以有效提高开发效率
批量设置值
mset key value [key value ...]
批量获取值
mget key [key ...]
redis怎样更新值而不重置过期时间
TimeSpan spanTimeoutLeft = redisExpertCodesCacher.KeyTimeToLive(loginHelper.UserName);//获得key目前的剩余过期时间 bool b = redisExpertCodesCacher.SetAddExpertCode(loginHelper.UserName, q, spanTimeoutLeft);//使用Set存储 是否需要判断学者代码是否存在?如果不存在则添加