Redis

Redis总结

Posted by Bug1024 on January 7, 2017

特点

  • 高性能Key-Value存储
  • 丰富的数据结构:string、list、hash、set、zset、hypeloglog
  • 支持数据过期:主动过期+惰性过期
  • 支持多种LRU策略:volatile-lru、volatile-ttl 等
  • 内存管理:tcmaloc、jemalloc
  • 内存存储+磁盘持久化: rdb、aof
  • 支持主从复制
  • 单线程

配置

aof配置

    appendonly yes 是否打开aof日志功能
    appendfsync always 每一个命令都立刻同步到aof,安全但是速度慢,此时和传统的DB持久化是类似的
    appendfsync everysec 折衷方案每秒一次,一般选用这种。
    appendfsync no 交给操作系统,由操作系统判断缓冲区大小,同意写入aof中,频率低速度快。
    no-appendfsync-on-rewrite yes 正在导出rdb文件,是否要停止aof
    auto-aof-rewrite-percentage 100 aof文件比起上次重写时的大小,增长率是百分之百时重写。
    auto-aof-rewrite-min-size 64mb 至少超过64m重写。

rdb配置

    save 10 100 10s后如果至少100个key发生变化则生成rdb
    save 100 50 可以多个,任意一个条件满足即可触发
    dbfilename dump.rdb 指定rdb保存到本地数据库文件名
    stop-writes-on-bgsave-error yes 当硬盘因为权限等原因无法写入时,停止写入
    rdbchecksum yes 对rdb文件进行校验

主从配置

    slaveof master_ip master_port 设置为某个master的slave
    slaveof on one 恢复为master,不会丢失已经同步的数据

持久化

同时开启两种持久化方式,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件 保存的数据集要完整。 虽然SAVE会一直阻塞Redis直到快照生成完毕,但是因为它不需要创建子进程,所以不会像BGSAVE一样因为创建子进程而导致Redis停顿

主从同步原理

  • slave向master发送sync指令,master接收到时调用bgsave指令fork一个子进程进行持久化工作,该期间master的写指令都缓存在内存中
  • bgsave指令完成后master会将rdb文件发送给slave,slave接收到后将其存在磁盘上,然后读入内存,这个动作完成后master会将这段时间缓存的写指令再以redis协议的格式发送给slave
  • 2.8版版本引入增量同步机制

热部署原理

master不负责具体的工作,而是调用worker工作,它只是负责读取配置文件,因此当一个模块修改或者配置文件发生变化,是由master进行读取,因此此时不会影响到worker工作。 在master进行读取配置文件之后,不会立即的把修改的配置文件告知worker。而是让被修改的worker继续使用老的配置文件工作,当worker工作完毕之后,直接当掉这个子进程,更换新的子进程,使用新的规则。

事务

  • MULTI用来组装一个事务
  • EC用来执行一个事
  • DISCARD用来取消一个事务
  • WATCH用来监视一些key,一旦这些key在事务执行之前被改变,则取消事务的执行
     # 如果在 WATCH 执行之后, EXEC 执行之前, 有其他客户端修改了 mykey 的值, 那么当前客户端的事务就会失败。 程序需要做的, 就是不断重试这个操作, 直到没有发生碰撞为止,这种形式的锁被称作乐观锁
     WATCH mykey
        val = GET mykey
        val = val + 1
     MULTI
        SET mykey $val
     EXEC
    

Redis Cluster

  • Redis 集群不像单机Redis 那样支持多数据库功能, 集群只使用默认的 0 号数据库, 并且不能使用 SELECT 命令。
  • 节点之间使用Gossip 协议 来进行以下工作

数据结构

  • String SDS 二进制安全 记录length
  • HyperLogLog 基数估算 每个键占用的内容都是12K 可以非常省内存的去统计各种计数,比如注册ip数、每日访问IP数、页面实时UV(PV肯定字符串就搞定了)、在线用户数等

为什么会丢数据/产生脏数据

  • Redis是一个注重性能的NoSQL,在数据一致性方面不强
  • Redis的复制是异步的,即主从实例之间数据可能存在1~10秒的差距
  • 切换过程当中不会判断主从数据是否一致

分布式方案

  • Codis 豌豆荚出品
  • twemproxy 推特出品