Reids集群知识

知识回顾:

redis是单机单进程的,可做缓存可做数据库,

持久化方案:RDB和AOF,如果当作缓存用RDB就够了,如果当作数据库要开启AOF;

RDB(relation-ship database)持久化:

默认redis会以一个rdb快照的形式,将一段时间内的数据持久化到硬盘,保存成一个dumpr.rdb二进制文件。
工作原理:当redis需要持久化时,redis会fork一个子进程,子进程将数据写到磁盘上临时一个RDB文件中。当子进程完成写临时文件后,将原来的RDB替换掉,这样的好处就是可以copy-on-write。

//配置redis.conf:
save 900 1
save 300 10
save 60 10000

//在900秒内,如果有一个key被修改,则会发起快照保存。300秒之内,如果超过10个key被修改,则会发起快照保存。在60秒内,如果1w个key被修改,则会发起快照保存。

aof(append-only file)持久化:
默认会以一个appendonly.aof追加进硬盘。

//redis.conf默认配置:
appendfsync yes
appendfdync always
//每次有数据修改都会写入AOF
appendfsync everysec
//每秒同步一次,策略为AOF的缺省策略

  

存在问题:1、单点故障;2、容量有限;3、压力(i/o压力、连接数压力)

解决的方式是,将单节点变为多节点:

1、读写分离

2、基于三维进行扩展AKF

微服务拆分原则:

  1、AFK拆分原则;

  2、前后端分离原则;

  3、无状态服务

  4、RestFul通讯风格

AKF拆分原则:X:全量镜像(主可发生读写,备只能读)

       Y:按照不同业务,将不同数据存储到不同的redis中

       Z:按照优先级,逻辑再划分

通过AFK一变多,问题:数据一致性问题。

方案:1、强一致性,所有节点阻塞直到数据全部一致;极易破坏可用性;

      2、弱一致性,通过异步方式,容忍数据丢失一部分。

   3、最终数据会一致,可在中间加入中间件,比如kafka

集群方式:

分布式常见的几个架构:

主备:主机死了,备机可以顶

主从(对主做HA高可用):主机后面有几个从节点。(redis用的是主从复制);

主从复制架构,又面临一个问题,单点故障怎么解决?

我们对主进行HA架构,用一个程序进行监控,该监控程序,为了避免单点故障,那么也必须是一个集群架构。

我们的监控设备一定是奇数台,进行过半选举,如果过半都选举故障,那么,将会跳到另一台节点。

推导:1、统计不准确,不够势力范围;问题:网络分区、脑裂

CAP原则

不能解决容量的问题,在X轴方向做集群;

哨兵

1、启动3个哨兵,进行监控

redis-server ./26379.conf --sentinel
//也可以直接启动redis-sentinel
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2

26379.conf文件只需要2行

第二行语义:哨兵 监控 监控名 ip 端口 几票通过

需要过30秒哨兵才能生效

 reids单节点容量问题解决方案

可以进行业务拆分,数据分类;到了数据不能拆分的时候,可以进行数据分片;

1、哈希取模hash+取模(弊端:模数固定,节点的拓展比较麻烦,新增一台机器必须重新取模);

2、随机random(弊端:取回数据的时候比较麻烦,需要便利)

3、一致性哈希算法(优点:的确可以分担其他节点的压力,也不会造成全局洗牌。弊端:新增系欸但会造成一小部分数据无法名中)

没有取模,client的key和node都需要进行计算,规划成一个哈希环

导致的问题:

1.可能造成击穿

2.增加复杂度,每次取离数据最近的2个物理节点

哈希环上的节点数尽可能多,可以解决数据倾斜的问题,也就是虚拟节点技术.

 方案:设法取离我最近的2个物理节点

该方案更倾向于作为缓存,而不是数据库使用

客户端连接过多问题

redis的连接成本很高,对server端,引入代理proxy

在linux版本比较低时可升级一下

yum update nss
//搜索安装软件
yum search xxx
//安装软件
yum install xxx

twemproxy

twemproxy是一种代理分片机制,由twitter开源,twemproxy作为代理,可以接受多个程序访问,按照路由规则,转发为后台各个Redis服务器,再进行原路返回,该方案很好的解决了Redis实例承载能力问题。

安装:

git clone https://github.com/twitter/twemproxy.git
//如果报错,执行:yum update nss
yum install automake libtool
autoreconf -fvi
//如果报错,执行
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
yum clean all
yum install autoconf268.noarch -y
autoreconf268 -fvi
./configure --enable-debug=full
make
//查看服务文件
cd scripts
nutcracker.init
//拷贝这个文件进/etc/init.d目录
//拷贝编译运行文件进/usr/bin目录
//拷贝conf文件夹进/etc/nutcracker目录
//进入/etc/nutcracker,修改nutcracker.yml进行配置

alpha:
  listen: 127.0.0.1:22121
  hash: fnv1a_64
  distribution: ketama
  auto_eject_hosts: true
  redis: true
  server_retry_timeout: 2000
  server_failure_limit: 1
  servers:
   - 127.0.0.1:6379:1
   - 127.0.0.1:6380:1

//之后开启nutcracker服务,开启service服务,之后连接redis-cli进行连接22121端口
我们通过nutcracker进行get和set,我们在nutcracker不支持的命令:
keys *
watch k1
multi
//这些命令都不支持

predixy软件,也可作为替代品  

wget https://github.com/joyieldInc/predixy/releases/download/1.0.5/predixy-1.0.5-bin-amd64-linux.tar.gz

修改predixy.conf  

打开Bind 127.0.0.1:7617
打开include sentinel.conf

修改26379的哨兵

port 26379
sentinel monitor ooxx 127.0.0.1 36379 2
sentinel monitor xxoo 127.0.0.1 46379 2

击穿&穿透&雪崩

击穿:

概念:redis作为缓存,设置了key的过期时间,key在过期的时候刚好出现并发访问,直接击穿redis,访问数据库

解决方案:使用setnx() ->相当于一把锁,设置的时候,发现设置过期,加锁,只有获得锁的人才可以访问DB,这样就能防止击穿。

逻辑

get key
setnx
if ok addDB
   else sleep 
        go to 1

问题1:如果第一个加锁的人挂了?

  可以设置过期时间

问题2:如果第一个枷锁的人没挂,但是锁超时了?

  可以使用多线程,一个线程取库,一个线程监控前一个线程是否存活,更新锁时间;

穿透

概念:从业务接收查询的是你系统根本不存在的数据,这时候刚好从redis穿透到数据

解决方案:

使用布隆过滤器,不存在的数据使用bitmap进行拦截

  1.使用布隆过滤器。从客户端包含布隆过滤器的算法。

  2.直接redis集成布隆模块。

问题1:布隆过滤器只能查看,不能删除?

  换cuckoo过滤器

雪崩:

概念:大量的key同时失效,造成雪崩。

解决方案:在失效的基础上,再加入一个时间(1-5min)

1、时效性无关的:随机过期时间

2、必须两点过期的,强依赖击穿方案,或者在业务层拦截请求,睡几秒秒然后放行

Redis做分布式锁

1、setnx

2、过期时间

3、守护线程,延长过期时间

还有redisson

zookeeper做分布式锁最方便

原文地址:https://www.cnblogs.com/dagreentree/p/13372360.html