Redis安装和使用

安装

  1. redis是C语言编写的, 要先安装gcc编译器
    yum -y install gcc automake autoconf libtool make

  2. 下载redis压缩包并解压到/usr/local/
    wget http://download.redis.io/releases/redis-5.0.8.tar.gz
    tar -zxvf redis-5.0.8.tar.gz -C /usr/local/

  3. 进入redis根目录, 编译redis代码
    cd redis-5.0.8 && redismake

  4. 安装redis
    make PREFIX=/usr/local/redis-5.0.8 install

安装完成后redis根目录下会新增bin目录, 里面放着redis的可执行文件

配置文件

  1. redis根目录下创建conf目录统一存放配置文件,新建redis.conf配置文件

  2. 使用配置文件启动redis
    ./redis-server conf/redis.conf

  3. 基本配置参数说明
    bind 127.0.0.1 限制访问IP
    port 6379 访问端口
    daemonize yes 后台启动
    dir /usr/local/redis-5.0.8/data 工作目录
    logfile "redis.log" 日志输出文件, 在工作目录中
    maxmemory 最大占用内存
    maxmemory-policy noeviction 淘汰策略

启动连接和关闭

启动redis服务有3种方式

  1. 直接使用bin目录下的 bin/redis-server
  2. 配置动态参数启动 bin/redis-server --port=6379
  3. 使用配置文件启动(推荐) bin/redis-server conf/redis.conf

连接redis客户端
bin/redis-cli -h 127.0.0.1 -p 6379

正常关闭redis服务
bin/redis-cli.sh -h 127.0.0.1 -p 6379 shutdown

如果配置了密码, 连接和关闭时需要加上-a 参数, 如
bin/redis-cli -h 127.0.0.1 -p 6379 -a ${password} shutdown

常用命令

keys * 查询所有的key,比较耗时,不建议使用
dbsize 查询数据总数
exists key 查询key存不存在,1:存在 , 0 :不存在
expire key seconds 给key设置有效期, 单位s
ttl key 查询key的剩余有效时间, -1:永久有效,-2:无效的key或已删除
persist key 设置key永久有效
del key 删除key,1:删除成功,0:删除失败
type key 查看key的数据类型
info 查看服务器信息

常用数据类型

http://redis.cn/commands.html

redis为什么这么快

  1. 内存存储
  2. 单线程处理数据,避免上下文切换和静态消耗,FIFO,无需加锁
  3. 使用epoll模型,非阻塞IO

数据淘汰策略

volatile-lru
优先从设定了过期时间的数据中,删除长时间未使用的数据
allkeys-lru
从所有的数据中删除长时间未使用的数据
volatile-random
优先从设置了过期时间的数据中随机删除
allkeys-random
从所有数据中随机删除
volatile-lfu
从设置了过期时间的数据中,删除使用次数最少的数据
allkeys-lfu
从所有的数据中删除使用次数最少的数据
volatile-ttl
对设置了过期时间的数据进行排序,删除剩余有效时间最少的数据
noeviction
内存不足时抛异常,不会删除数据

数据持久化

  1. RDB(快照)
    快照是将内存中的数据通过序列化并进行压缩,然后存入硬盘中。重启redis时会读取rdb文件恢复数据。
    触发方式:save命令(同步) bgsave命令(异步) 配置同步策略三种方式
    自动触发机制:全量复制 debug reload shutdown正常退出会自动触发数据同步

    配置:
    save 60 10000 备份策略
    dbfilename dump_6379.rdb RDB备份文件
    stop-writes-on-bgsave-error yes 是否在出现错误的时候终止RDB备份
    rdbcompression yes RDB备份文件是否进行压缩

    缺点:
    1)备份不及时,系统宕机可能会丢失数据
    2)性能较差。RDB不是增量备份,每次备份都会把所有的数据传输到磁盘。

  2. AOF
    AOF是把执行的命令写入到缓冲区,然后追加写入到磁盘中。通过读取并执行这些命令来恢复数据
    备份策略:
    always 每执行一条命令就备份到磁盘
    everysec 每隔一秒备份一次
    no 备份时机由操作系统决定
    重写:对写入.aof文件的命令进行优化

    配置:
    appendonly yes 是否开启AOF备份模式
    appendfilename "appendonly_6379.aof" AOF备份文件
    appendfsync everysec AOF备份策略
    no-appendfsync-on-rewrite yes 重写的时候是否执行AOF备份操作
    auto-aof-rewrite-percentage 100 触发重写的文件大小增长百分比
    auto-aof-rewrite-min-size 64m 触发重写的文件大小

  3. RDB和AOF混合模式
    配置:
    aof-use-rdb-preamble yes 使用RDB和AOF混合模式

主从复制

可以提高读数据的qps。设置方法:
方法1. 在需要设置为从节点的redis客户端使用命令
slaveof host port
方法2. 在配置文件中配置master的地址和端口
replicaof host port

哨兵机制

哨兵服务可以监测redis服务的运行状态,当有master服务器挂掉,会从剩余服务器中选举出新的master并修改其他slave服务器的master连接。

优点:可以解决单点故障,提高读数据的qps
缺点:无法提高写请求的qps,存储容量有局限性

配置

bind 127.0.0.1 限制访问IP
port 26380 访问端口
daemonize yes 后台启动
dir /usr/local/redis-5.0.8/data 工作目录
logfile "sentinel_26380.log" 日志输出文件, 在工作目录中
protected-mode no 是否开启保护模式

告诉sentinel去监听指定ip和port的一个master,master-name是集群的名字,quorum是指定当多少个sentinel认为这个master失效时,master才算真正失效
sentinel monitor ${master-name} ${ip} ${port} ${quorum}

master失效多长时间才会被sentinel认为是不可用的,单位毫秒,默认30秒
sentinel down-after-milliseconds master-name 30000

在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步。这个数字越小,同步时间越长,数字越大,就有越多的slave因为replication操作而不可用。可以设置为1来保证同时只有一个slave不能处理请求
sentinel parallel-syncs ${master-name} 1

master服务器失效之后隔多长时间再次检查该服务器的状态
sentinel failover-timeout ${master-name} 180000

启动

bin/redis-sentinel conf/sentinel_26380.conf

集群

相对于哨兵机制:

  1. 有多台写服务器,可以提高写数据的qps
  2. 数据分散存储,提高数据量
  3. 提高带宽、网络流量

配置:
cluster-enabled yes 开启集群模式
cluster-config-file node_6379.conf 集群服务器的信息
cluster-node-timeout 15000 节点间通信超时时间
cluster-require-full-coverage no 集群中一个节点出现故障,是否停用整个集群

数据分区规则
  1. 顺序分区
    特点:
    1)数据容易倾斜
    2)键值分布和业务相关
    3)支持批量操作
    4)可以顺序访问

  2. Hash分区
    特点:
    1)数据分散度高
    2)键值分布与业务无关
    3)支持批量操作
    4)无法顺序访问

    Hash分区方案:
    1)节点取余
    根据Hash值 % 分区数量进行分区
    注意点:节点取余扩容时,为了减少数据的迁移量,尽量翻倍扩容(50%迁移量)

    2)一致性Hash
    采用Hash环的概念,Hash结果是int类型,有0-2^32个数值,这些数值连在一起首尾相接形成一个环,在这个 环上均匀的分配节点,每个节点负责一块区域

    Hash环@2x.png

    当插入或查询一个key时,首先对key做Hash运算得到Hash值,然后根据这个Hash值顺时针找到对应的节点进行存储和读取
    特点:
    ① 在客户端对key进行Hash运算,然后找到对应的节点进行存储和读取
    ② 扩容或者删除节点只会影响下一个相邻的节点,不会对其他节点产生影响
    ③ 翻倍扩容,扩容时在每块区域分别添加新的节点,以保证最小数据迁移量和负载均衡
    ④ 扩容后数据不会自动迁移,需要在客户端手动迁移数据。如果是缓存数据,可以从数据库查询之后再进行缓存,无需迁移数据,所以Hash环比较适合做缓存

3)虚拟槽
redis将16384个虚拟槽平均分配到节点服务器中,每个节点服务器都知道其他服务器中有哪些槽。操作时会对key进行CRC16(key) % 16383运算,得到的结果就是所在的槽的编号,节点服务器接收到请求后,如果计算出来的槽在当前节点,就直接进行数据操作,如果不在当前节点,会连接到对应的服务节点进行操作。

集群搭建流程
  1. 配置并启动集群的服务器
    从redis5版本官方提供了一个命令可以自动发现服务器、分配虚拟槽和设置从服务器,无需手动操作后面2 3 4 步
    redis-cli --cluster create ${host1:port1 host2:port2 ...} --cluster -replicas ${slave_ratio}
    slave_ratio 是从服务器占比,设置为2就是主从1:2,设置为3就是主从1:3
  1. 发现其他服务器
    cluster meet ${host} ${port} 发现指定服务器
    cluster nodes 或者cluster info命令查看已发现的服务器信息

  2. 分配虚拟槽
    虚拟槽只分配给master服务器
    虚拟槽一共16384个,可以通过脚本循环执行下面命令给指定服务器分配虚拟槽
    redis-cli -h ${host} -p ${port} cluster addslots ${slot}

  3. 设置从服务器
    redis-cli -h ${host} -p ${port} cluster replicate ${master_node_id}
    master_node_id可以通过cluster nodes命令查看

Redis常见问题

  1. 缓存穿透:
    缓存穿透一般出现在查询数据库中不存在的数据。缓存没有命中就会查数据库, 数据库查不到也不写入缓存,就会导致这个不存在的数据每次都要查询数据库,增加数据库的压力

    解决方案:
    1)单个key穿透,可以将这个key在redis中缓存一个空值,设置较短的有效期,防止高频率的查询数据库
    2)多个key穿透,可以通过验证key的合法性来决定是否查询数据库。如果数据量不大,可以把所有的key放到redis的set集合中,查询时判断key如果在set集合中,再查数据库。如果数据量上亿,可以考虑使用布隆过滤器来实现。

  2. 雪崩:
    雪崩是指大量缓存在同一时间失效,所有的请求都会查询数据库,造成数据库崩溃。

解决方案:
1)尽量让key的过期时间均匀分布
2)控制同一个key查询数据库的线程数量,在查询数据库之前再次查询缓存。常见的限流算法有计数算法、滑动窗口、令牌桶、漏桶等

  1. 热点key:
    热点key是指某个key的访问频率非常频繁,导致redis服务器压力剧增,无法保证正常提供服务

解决方案:
1)横向扩容,增加集群服务器提高读数据的能力
2) 使用本地缓存。把热点数据缓存在本地服务器的内存中,减少redis的访问量

SpringBoot项目集成Redis

  1. 导入redis包spring-boot-starter-data-redis和连接池包commons-pool2
  2. yml文件中配置redis
redis:
    cluster:
      nodes: 127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382,127.0.0.1:6384,127.0.0.1:6385,127.0.0.1:6386
    lettuce:
      pool:
        min-idle: 10
        max-idle: 10
        max-active: 10
        max-wait: 150000
  1. 使用redisTemplate操作redis
 @Autowired
 private RedisTemplate redisTemplate;

 //  拿到ValueOperations对象操作redis
 ValueOperations<String,String> ops = redisTemplate.opsForValue();
 String str = ops.get("key");
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容