Redis 实践-工具改变人的思考方式

Redis 简介

Redis 简介

  • 非关系数据库
  • 可以存储key和5种不同类型的值Value
  • 可以将存储在内存中的数据持久化到硬盘
  • 可以使用复制特性来扩展读性能
  • 可以使用客户端分片来扩展写性能(线性提升)
    • 客户端分片:基于hash或者包含键的Id将数据存储到多台机器,也可以从多台机器里面获取数据,这种办法在处理某些问题时可以获得线性级别的性能提升。
  • redis 不支持嵌套结构特性(如果需要可以通过合理组织命名空间一定程度上行模拟。)

和memcache对比

  • 和memcached的对比
    • 都可用于存储键值对
    • 性能相差无几
    • 部署成本接近(要求越高memcache越便宜)
    • redis集群功能受限制比较严重,大规模应用没有明显的优势
    • redis单机功能完爆memcache
    • redis单机很难升级(一般都是加机器做分片或者弄主从,升级到集群版依赖历史代码,集群环境下很多命令不支持,比主从的要求苛刻很多)
    • Redis可以以两种方式进行持久化
    • Redis除了存储字符串之外还可以存储其他4种结构
    • 结论:redis可以作为主数据库使用,又可以作为其他存储系统的辅助数据库

阿里云 redis 标准版 的使用场景

  • 对 Redis 协议兼容性要求较高的业务
    • 标准版完全兼容 Redis 协议,业务可以平滑迁移。
  • Redis 作为持久化数据存储使用的业务
    • 标准版提供持久化机制及备份恢复机制,极大的保证数据可靠性。
  • 单个 Redis 性能压力可控
    • 由于 Redis 原生采用单线程机制,性能在10wQPS以下的业务建议使用。如果需要更高的性能要求,请选用集群版本。
  • Redis 命令相对简单,排序、计算类命令较少
    • 由于 Redis 的单线程机制,CPU会成为主要瓶颈。如排序、计算类较多的业务建议选用集群版配置。

持久化选项(两种方式)

  • 时间点转储(快照方式)
    • 指定时间段内有指定数量的写操作(bgsave)
    • 使用(SAVE/BGSAVE)两者之一
    • 关闭(SHUTDOWN)时会执行阻塞save
    • 从服务器开始sync命令时会执行bgsave
  • 只追加写入(AOF)
    • 将所有修改了数据库的命令都写入一只追加的文件里面,用户可以根据数据的重要程度,将只追加的文件里面,用户可以根据数据的重要程度将只追加写入设置为:从不同步、每秒同步一次、或者每写入一次命令就同步一次。

两种方法可以都用也可以都不用很随意

bgsave的创建子进程速度非常快(几GB毫秒级,取决于剩余内存,就是有没有使用虚存),慢的是存到硬盘上
AOF的问题是AOF文件会比较大,所以需要执行BGREWRITEAOF来压缩AOF文件的体积,这个命令通过移除冗余命令来实现。

主从复制

  • 执行复制的从服务器会链接上主服务器,接受主服务器发送的整个数据库的初始副本;然后主服务器执行的写命令都会发送给从服务器去执行,从而实时的更新从服务器的数据集。

从服务器在执行同步时,会清空自己的所有数据
Redis不支持主主复制(Redis cluster)

字符串处理

  • 长度
    • 整数:和系统的长整型相同(32/64位有符号整数)
    • 浮点数:双精度浮点数(doubule)
  • INCR/DECR
    • 如果一个值可以被解释为整数或者浮点数那么redis允许用户执行这些命令,反之则会报错
    • 对一个不存在的键执行INCR那么redis会把这个键的值当成0来处理

不常用但很有用的命令

  1. 字符串

SETNX、APPEND、GETRANGE、SETRANGE、GETBIT、SETBIT、BUTCOUNT、BITOP

  1. 链表

LINDEX、LRANGE、LTRIM

  1. 集合

SRANDOMMEMBER、SPOP、SMOVE

  1. 散列

HKEYS、HVALS

  1. 有序集合

有序集合并运算比较特殊可以用来解决一些权重问题:ZINTERSTORE、ZUNIONSTORE

  1. SORT

根据给定选项,对输入列表、集合或者有序集合进行排序,然后返回存储排序的结果

  1. KEY相关命令
命令 功能
PERSIST 移除键的过期时间
[P]TTL 查看还有多久过期
[P]EXPIRE 设置键的过期时间
[P]EXPIREAT 设置键的过期时间为指定时间戳

事务和流水线

  • Redis 事务以MULT开始以exec结束,在EXEC执行之前不会执行任何实际的操作,所以用户没有办法根据读取到的数据来做决定。
  • 使用WATCH/DISCARD(UNWATCH)的乐观锁来避免并发环境下数据出错

为什么redis没有实现典型的悲观锁功能?
悲观锁持有锁的客户端运行越慢,等待解锁的客户端被阻塞的时间就越长。
reids的setnx命令配合lua脚本可以很方便的实现高性能的分布式悲观锁。

  • 非事务流水线:multi/exec会保证事务原子性,而这也是有开销的,redis会为每个客户端创建一个任务队列处理事务,也会消耗资源。常用的客户端都封装了一种pipeline方式,来处理一个命令的执行结果不会影响另一个命令的输入的场景。

redis里就没有pipeline这个命令,只是各种redis客户端实现的一种方式(打个比方Yii2默认的reids客户端就没实现这个功能。)

典型实践

  1. 分布式锁:悲观锁,消除竞争条件
  2. 公平计数信号量:限制资源(API)的并发数量(通过计数器替换时间戳作为信号量分值)

计数器信号量和锁的区别在于客户端获取锁失败时一般会等待,而计数器信号量会选择直接返回错误

  1. 任务队列:
    • 优先级队列:blpop命令支持多个列表作为参数并按照顺序弹出数据,实现很简单(ResQueue)
    • 延迟任务队列(3种简单实现方式):
      1. 在任务信息中包含任务的额执行时间,如果时间没到呢,短暂等待把任务重新推入队列里面
      2. 使用等待列表记录需要在未来执行的任务,并在每次进行循环的时候,检查并执行已经到期的任务
      3. 把所有需要在未来执行的任务放有序集合里,并将执行时间设置为分值,扫描并移除合适的任务,并添加到合适的任务队列。

Redis优化

降低内存占用

降低redis内存的占用有助于减少创建快照和加载快照所需的时间、缩短从服务器进行同步所需要的时间(同步初始化那步的时间,主从同步靠的是发送命令也就是不能降低delay)

  1. 使用短结构来更高效的表示数据
  2. 使用分片技术将体积较大的结构分割为多个体积较小的结构(单机分片)
  3. 将固定长度的数据打包存储到字符串键里面,从而进一步降低内存占用

扩展Redis

前提:
确认合理使用了Redis提供的数据结构(比如:不把列表当集合使用;也不要获取整个散列然后在客户端里进行排序,而是直接使用有序集合);合理使用流水线和连接池;将大体积的对象缓存到Redis里面之前应该合理进行压缩(lz4、gzip、bzip2)
做完上述准备之后可以考虑架构上扩展读写性能了

  1. 扩展读性能
    • 扩展读性能的最简单方法就是添加只读从服务器
    • 使用从服务器树来解决重同步的问题
    • 使用Redis Sentinel 对下线的主服务器提供故障转移功能(RS还提供了转移通知的功能,可以在故障转移的时候调用用户脚本。)
    • 使用带压缩的隧道来减低从服务器的传送的数据量(如果使这个功能需要ssh自带的选项让ssh自动重连)

重同步:每当有从服务器尝试与主服务器建立连接的时候,主服务器就会为从服务器传建一个快照,如果在快照创建完毕之前,有多个服务器都尝试与主服务器进行连接,那么这些从服务器将会接收到同一个快照。从效率角度将这是合理的,但是这可能会将主服务器的带宽打满,导致主服务器的延迟变高甚至导致主服务器已经建立的链接被断开。

  1. 扩展写性能

前提:
1.进行功能拆分
2.在对redis写入之前,先尝试在本地内存中对将要写入的数据进行聚合计算
3.使用锁或者Lua脚本去替换redis事务段
在以上方法都试过后说明遇到了只使用一台机器带来的瓶颈,是时候将数据分片到多台机器上面了
数据分片的架构有很多种

  1. 可以使用分片来扩展复杂查询

Lua 脚本编程

Redis的Lua脚本编程的实现和典型应用

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

推荐阅读更多精彩内容