关于Redis应该知道

Redis

redis能干什么?

  1. 内存存储、持久化,内存中断电既失,持久化很重要(rdb、aof)
  2. 效率高,可用于高速缓存
  3. 发布订阅系统
  4. 地图信息分析
  5. 计时器、计数器(浏览量 )

redis是单线程的为什么还这么快?

redis是将所有数据放在内存中的,使用单线程的效率就是最高的(多线程会导致上下文切换,耗时的操作)

五大数据类型

String(字符串)

String类似的使用场景:value除了是字符串还可以是数字

  • 计数器
  • 统计多单位的数量 eg: uid:1881:star 0 (incr/decr)
  • 粉丝数
  • 对象缓存存储

List(列表)

所有的list命令都是l开头的

  • 实际上是一个链表,before Node after left right 都可以插入值
  • 如果key不存在,创建新的链表
  • 如果key存在,新增内容
  • 如果移除所有值,空链表也代表不存在
  • 两边插入或改动值,效率最高,中间插入效率低一些
  • 消息队列 (Lpush/Rpop) 栈(Lpush/Lpop)

Set(集合)

set中的值是不能重复的,无序不重复集合

支持交、并、差

  • SDIFF key1 key2 差集
  • SINTER key1 key2 交集
  • SUNION key1 key2 并集

Hash(哈希)

Map集合,Key-Map集合,这个时候值是一个map集合,本质和String没有太大区别

Hash更适合存储对象,String更加适合字符串存储

Zset(有序集合)

set排序 存储班级成绩表,工资排序表

普通消息,重要消息排序,带权重进行判断

实现排行榜 topN

三大特殊类型

geospatial地理位置

朋友的定位、附近的人,打车的距离计算

GEO底层使用的是Zset,可以使用Zset来操作geo

Hyperloglog

基数:不重复的元素

Bitmaps

位存储

事务

Redis事务本质,是一组命令的集合!一个事务中所有的命令都会被序列化,在事务执行的过程中,会按照顺序执行。一次性、顺序性、排他性

Redis单条命令是保证原子性的,事务是不保证原子性的!

Redis事务没有隔离级别的概念

Redis事务:

  • 开启事务(multi)
  • 命令入队(…)
  • 执行事务(exec)

监控!Watch(面试常问)

乐观锁

很乐观,认为什么时候都不会出问题,做什么都不会加锁,更新数据的时候去判断一下,在此期间是否有人修改过这个数据,version实现

  • 获取version
  • 更新的时候比较version

悲观锁

很悲观,认为什么时候都会出问题,无论做什么都会加锁。效率很差

Redis持久化

Redis是内存数据库,如果不将内存中的数据保存到磁盘,那么一旦服务器进程退出,服务器中的数据也会消失,所以redis提供了持久化功能。

rdb:产生dump.rdb文件持久化

aof:记录执行命令进行持久化

RDB比AOF更加高效

AOF(Append Only File)将我们所有的命令都记录下来,恢复的时候,将所有的命令都执行一边

AOF优缺点

优点

  • 每一次修改都同步,文件的完整会更加好
  • 默认每秒同步一次,可能会丢失一秒的数据
  • 从不同步效率最高高

缺点

  • 相对于数据文件来说,aof远远大于rdb,修复速度也比rdb慢
  • aof运行效率也要比rdb慢,所以我们redis默认的配置就是rdb持久化

Redis发布订阅

  • 第一个 redis-cli 客户端输入 SUBSCRIBE runoobChat,意思是订阅 runoobChat 频道。

  • 第二个 redis-cli 客户端输入 PUBLISH runoobChat “Redis PUBLISH test” 往 runoobChat 频道发送消息,这个时候在第一个 redis-cli 客户端就会看到由第二个 redis-cli 客户端发送的测试消息。

Redis主从复制

数据的复制是单向的,只能由主节点到从节点

读写分离,从节点一般用于读请求,主节点用于写请求

# Replication
role:master
connected_slaves:0
master_replid:c60b8c26f8fff361d247a88882c077c5f5bf11de
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

复制三个配置文件(redis.conf),修改对应的配置文件

  1. 端口
  2. pid名称
  3. 日志文件名称
  4. dump.rdb文件名称

主从配置

默认情况下每一台redis服务器都是主节点,一般情况下只配置从机

#配置主节点信息
127.0.0.1:6379> slaveof host port

主节点可以写入数据,从节点不能写入数据只能读,主节点写入的数据都会复制到从节点

如果是使用命令行,来配置的主从,这个时候如果重启了,就会变回主机!只要变回从机数据立马就能从主机获得!

哨兵模式

(自动选举老大)

配置

1.配置哨兵的配置文件sentinel.conf

#sentinel monitor 被监控的名称 host port 1
sentinel monitor myredis 127.0.0.1 6379 1

后面的数字1,代表主机挂了,slave投票看看让谁接替成为主机,票数最多的就会成为主机

2.启动哨兵模式

redis-sentinel sentinel.conf

优缺点

优点
  • 哨兵集群,基于主从复制模式,所有的主从配置优点他都有
  • 主从可以切换,故障可以转移,系统可用性会更好
  • 哨兵是主从模式的升级,手动到自动更加健壮
缺点
  • Redis不好在线扩容,集群一旦达到上限,在线扩容十分麻烦
  • 配置比较麻烦,里面有很多选择

完整配置文件sentinel.conf

# Example sentinel.conf

# *** IMPORTANT ***
# 绑定IP地址
# bind 127.0.0.1 192.168.1.1
# 保护模式(是否禁止外部链接,除绑定的ip地址外)
# protected-mode no

# port <sentinel-port>
# 此Sentinel实例运行的端口
port 26379

# 默认情况下,Redis Sentinel不作为守护程序运行。 如果需要,可以设置为 yes。
daemonize no

# 启用守护进程运行后,Redis将在/var/run/redis-sentinel.pid中写入一个pid文件
pidfile /var/run/redis-sentinel.pid

# 指定日志文件名。 如果值为空,将强制Sentinel日志标准输出。守护进程下,如果使用标准输出进行日志记录,则日志将发送到/dev/null
logfile ""

# sentinel announce-ip <ip>
# sentinel announce-port <port>
#
# 上述两个配置指令在环境中非常有用,因为NAT可以通过非本地地址从外部访问Sentinel。
#
# 当提供announce-ip时,Sentinel将在通信中声明指定的IP地址,而不是像通常那样自动检测本地地址。
#
# 类似地,当提供announce-port 有效且非零时,Sentinel将宣布指定的TCP端口。
#
# 这两个选项不需要一起使用,如果只提供announce-ip,Sentinel将宣告指定的IP和“port”选项指定的服务器端口。
# 如果仅提供announce-port,Sentinel将通告自动检测到的本地IP和指定端口。
#
# Example:
#
# sentinel announce-ip 1.2.3.4

# dir <working-directory>
# 每个长时间运行的进程都应该有一个明确定义的工作目录。对于Redis Sentinel来说,/tmp就是自己的工作目录。
dir /tmp

# sentinel monitor <master-name> <ip> <redis-port> <quorum>
#
# 告诉Sentinel监听指定主节点,并且只有在至少<quorum>哨兵达成一致的情况下才会判断它 O_DOWN 状态。
#
#
# 副本是自动发现的,因此您无需指定副本。
# Sentinel本身将重写此配置文件,使用其他配置选项添加副本。另请注意,当副本升级为主副本时,将重写配置文件。
#
# 注意:主节点(master)名称不能包含特殊字符或空格。
# 有效字符可以是 A-z 0-9 和这三个字符 ".-_".
sentinel monitor mymaster 127.0.0.1 6379 2

# 如果redis配置了密码,那这里必须配置认证,否则不能自动切换
# Example:
#
# sentinel auth-pass mymaster MySUPER--secret-0123passw0rd

# sentinel down-after-milliseconds <master-name> <milliseconds>
#
# 主节点或副本在指定时间内没有回复PING,便认为该节点为主观下线 S_DOWN 状态。
#
# 默认是30秒
sentinel down-after-milliseconds mymaster 30000

# sentinel parallel-syncs <master-name> <numreplicas>
#
# 在故障转移期间,多少个副本节点进行数据同步
sentinel parallel-syncs mymaster 1

# sentinel failover-timeout <master-name> <milliseconds>
#
# 指定故障转移超时(以毫秒为单位)。 它以多种方式使用:
#
# - 在先前的故障转移之后重新启动故障转移所需的时间已由给定的Sentinel针对同一主服务器尝试,是故障转移超时的两倍。
#
# - 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。
#
# - 取消已在进行但未生成任何配置更改的故障转移所需的时间
#
# - 当进行failover时,配置所有slaves指向新的master所需的最大时间。
#   即使过了这个超时,slaves依然会被正确配置为指向master。
#
# 默认3分钟
sentinel failover-timeout mymaster 180000

# 脚本执行
#
# sentinel notification-script和sentinel reconfig-script用于配置调用的脚本,以通知系统管理员或在故障转移后重新配置客户端。
# 脚本使用以下规则执行以进行错误处理:
#
# 如果脚本以“1”退出,则稍后重试执行(最多重试次数为当前设置的10次)。
#
# 如果脚本以“2”(或更高的值)退出,则不会重试执行。
#
# 如果脚本因为收到信号而终止,则行为与退出代码1相同。
#
# 脚本的最长运行时间为60秒。 达到此限制后,脚本将以SIGKILL终止,并重试执行。

# 通知脚本
#
# sentinel notification-script <master-name> <script-path>
#
# 为警告级别生成的任何Sentinel事件调用指定的通知脚本(例如-sdown,-odown等)。
# 此脚本应通过电子邮件,SMS或任何其他消息传递系统通知系统管理员 监控的Redis系统出了问题。
#
# 使用两个参数调用脚本:第一个是事件类型,第二个是事件描述。
#
# 该脚本必须存在且可执行,以便在提供此选项时启动sentinel。
#
# 举例:
#
# sentinel notification-script mymaster /var/redis/notify.sh

# 客户重新配置脚本
#
# sentinel client-reconfig-script <master-name> <script-path>
#
# 当主服务器因故障转移而变更时,可以调用脚本执行特定于应用程序的任务,以通知客户端,配置已更改且主服务器地址已经变更。
#
# 以下参数将传递给脚本:
#
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
#
# <state> 目前始终是故障转移 "failover"
# <role> 是 "leader" 或 "observer"
#
# 参数 from-ip, from-port, to-ip, to-port 用于传递主服务器的旧地址和所选副本的新地址。
#
# 举例:
#
# sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

# 安全
# 避免脚本重置,默认值yes
# 默认情况下,SENTINEL SET将无法在运行时更改notification-script和client-reconfig-script。
# 这避免了一个简单的安全问题,客户端可以将脚本设置为任何内容并触发故障转移以便执行程序。
sentinel deny-scripts-reconfig yes

# REDIS命令重命名
#
#
# 在这种情况下,可以告诉Sentinel使用不同的命令名称而不是正常的命令名称。
# 例如,如果主“mymaster”和相关副本的“CONFIG”全部重命名为“GUESSME”,我可以使用:
#
# SENTINEL rename-command mymaster CONFIG GUESSME
#
# 设置此类配置后,每次Sentinel使用CONFIG时,它将使用GUESSME。 请注意,实际上不需要尊重命令案例,因此在上面的示例中写“config guessme”是相同的。
#
# SENTINEL SET也可用于在运行时执行此配置。
#
# 为了将命令设置回其原始名称(撤消重命名),可以将命令重命名为它自身:
#
# SENTINEL rename-command mymaster CONFIG CONFIG


Redis缓存穿透和雪崩

缓存穿透(查询不到)

用户想要查询一个数据,发现Redis缓存数据库没有,也就是缓存没有命中,于是向持久层数据库查询,发现也没有,于是本次查询失败。当用户很多的时候,缓存都没有命中(秒杀),于是就请求了持久层数据库。这会给持久层数据库造成很大的压力,这时候就会出现缓存击穿。

解决方法:使用布隆过滤器,过滤掉无效请求

缓存击穿(量太大缓存过期)

一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,有大量的并发就会穿透缓存,直接访问数据库,会导致数据库瞬间压力过大

解决方法

1.设置热点数据永不过期

2.加互斥锁,保证每一个key同时只有一个线程去后端查询服务,其他线程没有获得分布式锁权限

缓存雪崩

在某一时间段,缓存集中过期失效。Redis缓存宕机了

解决方法

1.Redis高可用,多搞几台机器

2.限流降级,缓存失效后,通过枷锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和读写缓存,其他线程等待。

3.数据预热,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值