一. Redis 的优势
1. 大部分主流数据库只支持单一的数据结构, 比如传统的关系型数据库只支持二维表格, Memcache 只支持字符串的键值对, 而 Redis 支持多种数据结构: 字符串, 列表, 集合, 散列, 有序集合, HyperLogLog, 故此在诸多场景都有应用
2. 数据存储在内存, 读写速度极快
3. 数据在硬盘有备份, 便于故障恢复
4. 通过 Lua 脚本可以在服务器端执行用户定义的原子操作
二. Redis 数据结构
1. 字符串: 用于存储字符, 数字, 二进制数据, Redis 为这几种类型的数据分别定义了不同的操作命令
字符串基本操作: set key value; setnx key value; mset key value[key value....] ;msetnx key value[key value....]; getset key value; append key value; strlen key; setrange key index value; getrange key start end
数字基本操作: incrby key increment; decrby key decrement; incr key; decr key; incrbyfloat key increment
二进制数据基本操作: setbit key index value,bitcount key [start][end]; bitop operation(AND|OR|XOR|NOT) destkey key [key....]
2. 散列: 用于存储多个键值对, 好处是可以将相关的信息放在同一个位置, 便于管理; 另外, 创建键的数量相比直接使用字符串更少, 节约内存
基本操作: hset key field value; hsetnx key field value; hexists key field; hdel key field[field...]; hlen ke; hmset key field value[field value...]
- hkeys key (返回 key 包含的所有 field); hvals key (返回 key 包含的所有 value); hgetall key(返回 key 包含的所有 field value)
- hincrby key field increment; hincrbyfloat key field increment
3. 列表:
基本操作: lpush key value[value....] (类似于链表头插法);rpush key value[value....]; llen key; lindex key index; lrange key start stop; lset key index value; linsert key before|after pivot value
- lrem key count value (删除 count 个 value);
- ltrim key start stop; blpop key[key...] timeout(弹出首个非空列表最左端的项, 如果都为空则阻塞直到超时)
示例: 可以实现朋友圈时间线功能: 当用户发送一条朋友圈消息时, 为这条消息分配一个唯一 ID, 将消息推送到自己的 timeline 上, 并推送到所有朋友的 timeline 上
4. 集合: 无序集合, 可以计算并集, 交集, 差集
基本操作: sadd key element[element...]; srem key element[element...]; sismember key element; scard key(返回集合大小); smembers key(返回集合所有元素, 集合过大会造成 server 阻塞, 用 sscan 代替)
srandmember key [count](返回随机元素); sdiff key[key...] (计算差集); sdiffstore destkey key[key...] (计算差集并存储); sinter key[key...],sunion key[key...]
示例: 网站签到
5. 有序集合:
示例: 同样可以实现时间线, 每个用户需要两条时间线, 自己的时间线和自己及朋友的时间线集合中的元素为消息 ID, 分值为发送时间, 用户发送消息时, 将新消息的 ID 和分值用 ZADD 添加到有序集合里
6.HyperLogLog: 用来做基数 (集合中不同元素的数量) 统计的算法, 优点是, 在输入元素的数量或者体积非常非常大时, 计算基数所需的空间总是固定 的并且是很小的
介绍: 每个键只需要 12kb 内存, 即可存储 2^64 不同的基数
基本操作: pfadd key element[element]; pfcount key[key...]; pfmerge destkey sourcekey[sourcekey...]
示例: 每天网站独立 IP 个数
三. 持久化
1.RDB 持久化: Redis 为了提高查询效率, 数据都是存储在内存中, 同时, 为了提高可靠性, Redis 提供了两种持久化功能: RDB 与 AOF, 通过这两种方式, Redis 将存储在内存中的数据在硬盘中持久化成文件, 一旦发生宕机,
重启时可以重新载入这个文件, 保证数据不会丢失;
(1)手动 RDB 文件命令: save(会阻塞服务器); bgsave(fork 一个子进程创建 RDB, 完成后通知父进程)
(2)自动: save 配置项: save seconds changes (距离上次创建 RDB seconds 秒, 并且服务器发生不少于 changes 次修改), 则执行 bgsave
2.AOF 持久化: RDB 操作会将数据库所有内容进行保存, 因此执行时间及资源耗费很多, 执行的频率不能太高, 在两次创建 RDB 文件的间隙, 可以使用 AOF 持久化 AOF 的过程是每当数据库命令执行时, 将命令写入 AOF 文件
中现代的操作系统会有写缓存, 为了提高效率, 写文件时首先会写到一个 buffer 里, buffer 满了之后会调用 fsync(详见 http://blog.csdn.net/cywosp/article/details/8767327), 而 AOF 只有真正写到硬盘才不会丢失数据, Redis 提
供了配置控制写文件的时机: always(写一个命令调用一次 fsync, 效率会比较低), everysec(每秒调用一次, 默认),no(由操作系统控制)
AOF 重写: AOF 文件中保存的是命令, 因此占用空间比较大, Redis 通过 AOF 重写减小占用空间, 有几种方式触发 AOF 重写:
(1) 手动: bgrewrite 命令
(2) auto-aof-rewrite-percentage&auto-aof-rewrite-min-size 配置
四. Redis 多机
1. 单机的缺点: 内存容量不足; 单机 qps 有限
2. 主从复制: 从服务器处理部分或全部读请求, 降低了主服务的负载
创建方式: 1. 向一台 Redis 发送 slaveof masterIP masterPort 2. 配置文件中配置 slaveof 配置项
服务器下线: 从服务器下线后会降低处理读请求的能力; 主服务器下线后无法处理写请求, 读请求仍可以被从服务器处理, 但数据无法得到更新解决方式: 方式一: 手动向一台从服务器发送 slaveof no one, 让其变成主服务器, 逐个向其他
从服务器发送 slaveof 方式二: 使用 Redis Sentinel 监控主从服务器, 进行自动故障转移
3.twemproxy 提高写性能: 是一个客户端代理, 它根据用户选择的散列函数 (根据 Redis 键计算) 和分布函数(一致性哈希, 取模, 随机), 将数据分片存储在多个服务器上, 当 auto_eject_hosts 为 true, 并且连续多次写数据
发生错误时, 这台服务器被标记为下线, 将原本由这台服务器负责的数据交给其他服务器处理 server_retry_timeout 配置重新尝试写该服务器, 如果还是无法写入, 等待下次
4. 集群: Redis 的集群特性包括了上述的复制, 高可用和分片集群的复制特性与分片与前文所说的基本相同, 高可用与上述不同之处在于服务器的下线由集群中其他正常的主节点负责, 无需 Sentinel
集群会给每个节点分配一定的槽位, 对于不属于本节点负责的写请求 Redis 会返回一个重定向, 之后客户端重新向正确节点发送写请求
来源: http://www.bubuko.com/infodetail-2535467.html