Redis用途

1.缓存

  Redis提供了键值过期时间设置, 并且也提供了灵活控制最大内存和内存溢出后的淘汰策略。 可以这么说, 一个合理的缓存设计能够为一个网站的稳定保驾护航。

2.排行榜系统

 Redis提供了列表和有序集合数据结构, 合理地使用这些数据结构可以很方便地构建各种排行榜系统。

3.计数器应用

Redis适用于高并发的递增、递减功能

递增指令:incr(默认从0开始)

递减指令:decr(默认从0开始,递减会出现负数,这点跟memcache不一样,mc到0)

4.社交网络

赞/踩、 粉丝、 共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适合保存这种类型的数据,

Redis提供的数据结构可以相对比较容易地实现这些功能。

5.消息队列系统

Redis提供了发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够足够强大, 但是对于一般的消息队列功能基本可以满足。

6.共享Session

redis incr递增2 redis递减_缓存

7.限速

但是为了短信接口不被频繁访问, 会限制用户每分钟获取验证码的频率, 例如一分钟不能超过5次。

redis incr递增2 redis递减_数据库_02

一些网站限制一个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 incr递增2 redis递减_缓存_03

redis incr递增2 redis递减_缓存_04

redis incr递增2 redis递减_缓存_05

 

redis incr递增2 redis递减_redis incr递增2_06

Redis提供了简单的事务, 之所以说它简单, 主要是因为它不支持事务中的回滚特性。

 

redis incr递增2 redis递减_数据库_07

客户端

 

redis incr递增2 redis递减_Redis_08

redis incr递增2 redis递减_缓存_09

redis incr递增2 redis递减_缓存_10

 持久化

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 incr递增2 redis递减_缓存_11

Redis单线程架构导致无法充分利用CPU多核特性, 通常的做法是在一台机器上部署多个Redis实例。

复制

redis incr递增2 redis递减_redis incr递增2_12

redis incr递增2 redis递减_redis incr递增2_13

redis incr递增2 redis递减_redis incr递增2_14

拓扑

redis incr递增2 redis递减_缓存_15

redis incr递增2 redis递减_数据库_16

redis incr递增2 redis递减_缓存_17

redis incr递增2 redis递减_数据库_18

 

redis incr递增2 redis递减_数据库_19

redis incr递增2 redis递减_缓存_20

Redis的噩梦: 阻塞

 

redis incr递增2 redis递减_redis incr递增2_21

内存

 

redis incr递增2 redis递减_数据库_22

redis incr递增2 redis递减_缓存_23

哨兵

 

redis incr递增2 redis递减_redis incr递增2_24

redis incr递增2 redis递减_数据库_25

redis incr递增2 redis递减_Redis_26

redis incr递增2 redis递减_缓存_27

redis incr递增2 redis递减_Redis_28

redis incr递增2 redis递减_Redis_29

redis incr递增2 redis递减_数据库_30

redis incr递增2 redis递减_缓存_31

redis incr递增2 redis递减_缓存_32

redis incr递增2 redis递减_redis incr递增2_33

redis incr递增2 redis递减_数据库_34

redis incr递增2 redis递减_Redis_35

集群

 Redis Cluster是Redis的分布式解决方案, 在3.0版本正式推出, 有效地解决了Redis分布式方面的需求。 当遇到单机内存、 并发、 流量等瓶颈时, 可以采用Cluster架构方案达到负载均衡的目的。

 

redis incr递增2 redis递减_Redis_36

redis incr递增2 redis递减_redis incr递增2_37

1.节点取余分区

2.一致性哈希分区

3.虚拟槽分区

 

redis incr递增2 redis递减_缓存_38

redis incr递增2 redis递减_缓存_39

 

redis incr递增2 redis递减_缓存_40

redis incr递增2 redis递减_数据库_41

redis incr递增2 redis递减_redis incr递增2_42

缓存设计

 

redis incr递增2 redis递减_缓存_43

缓存穿透

缓存穿透是指查询一个根本不存在的数据, 缓存层和存储层都不会命中。(攻击者利用大量不存在的验证ID进行请求,导致了缓存穿透,引起后端数据库压力骤增而崩溃。)

redis incr递增2 redis递减_数据库_44

有效地解决缓存穿透

    有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,

  一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法(我们采用的就是这种),

  如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

redis incr递增2 redis递减_Redis_45

雪崩优化

redis incr递增2 redis递减_数据库_46

Redis监控运维云平台CacheCloud

 

redis incr递增2 redis递减_redis incr递增2_47

其他

批量操作命令可以有效提高开发效率

批量设置值

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存储 是否需要判断学者代码是否存在?如果不存在则添加