首页
技术博客
PHP教程
数据库技术
前端开发
HTML5
Nginx
php论坛
新用户注册
|
会员登录
PHP教程
技术博客
编程问答
PNG素材
编程语言
前端技术
Android
PHP教程
HTML5教程
数据库
Linux技术
Nginx技术
PHP安全
WebSerer
职场攻略
JavaScript
开放平台
业界资讯
大话程序猿
登录
极速注册
取消
热门标签 | HotTags
erlang
solr
plugins
actionscrip
command
list
nodejs
usb
iostream
split
yaml
foreach
node.js
future
tags
integer
require
search
blob
heatmap
dagger
bash
grid
jar
object
copy
frameworks
int
less
python
python3
audio
cmd
sum
php
input
buffer
lua
triggers
netty
const
config
cookie
typescript
random
数组
flutter
uml
get
format
tree
shell
range
runtime
loops
eval
filter
callback
md5
python2
cSharp
rsa
char
process
chat
export
vbscript
cPlusPlus
stream
settings
php7
php8
uri
bit
bytecode
text
metadata
c语言
request
当前位置:
开发笔记
>
编程语言
> 正文
【技术分享】代晓磊:大街网Redis集群运维之路
作者:范尼萧_659 | 来源:互联网 | 2023-06-13 11:26
本文对Redis集群进行了介绍,以及大街Redis集群运维之
本文整理自DTCC2016主题演讲内容,录音整理及文字编辑IT168@ZYY@老鱼。如需转载,请先联系本公众号获取授权!
演讲嘉宾
代晓磊
大街网数据库Cache负责人
曾就职于人人网,主要负责人人无线数据库维护、统计部门Inforbright数据仓库库维护。2013年-至今,大街网数据库Cache负责人。
分享内容
大家好,我是大街网的代晓磊,今天我演讲的主题是《Redis集群在大街网的应用实践》,我的分享主要分为以下几部分:
第一部分与大家分享“大街网Redis缓存架构之路”,主要经过了三个阶段,第一个阶段是单节点主从阶段,第二阶段是我们自建hash集群,最后一个也是最主要的阶段是Redis Cluster的应用。
早期的Redis使用是单节点的主从,并且所有的主节点都部署在同一台服务器,导致主服务器压力比较大,而从服务器没有任何请求。高可用是通过服务器级别的LVS+KeepAlive来实现,这种架构只有当主服务器宕机的时候,所有redis节点才能切换到备用服务器。因为高可用是基于服务器级别的,任何单事例的redis宕机都不会切换到备事例,会对业务造成较大的影响,并且Redis服务器的负载也不均衡。还有一个问题就是单Redis的容量和扩展性都没有。
基于单Redis主从的各种问题,我们就搭建了第二个架构——自建hash集群。优点是解决了单主从的性能或者扩展问题,但依然没有解决高可用问题,因为该hash集群没有挂载slave,也没有Redis实例宕机的切换逻辑。该架构主要有几个特点:引入ZooKeeper配置中心,程序访问的是配置中心的数据源,目的方便以后的迁移;引入封装好的中间层,该架构的优点是通过多个hash节点解决了单Redis带来的性能瓶颈, 封装好的中间层proxy做hash,通过一致性hash算法,使一个节点扩展到多个节点,这样的话它的并发,包括扩展性上都有一定的提升,最关键的是:依然没有解决高可用问题,任何一个hash节点的宕机,就会丢失1/N的线上请求(N是hash节点数)。
为了提供一个高可用、易维护的方案,我们推出了第三种架构:Redis Cluster。
我们首先对Redis Cluster进行简单的介绍,首先我们先说redis集群的优点:
(1)首先我们最关心的是高可用,Redis集群高可用是指在集群中master节点至少有1个slave节点存活的条件下,当master宕机,salve就会通过集群内部一半以上的节点投票选举为新的master节点。
(2)第二高性能,高性能是指集群不需要其他的中间件(比如proxy),降低了在中间件级别的性能消耗,并且没有了单节点中复杂的merge操作。
(3)扩展性好:当集群的空间以及性能出现瓶颈时,我们可以通过添加新的集群节点来水平扩展。注意集群并不是自动扩展,需要脚本支持。
(4)丰富的集群命令:redis cluster提供了丰富的集群命令,大家可以上官网(redis.io)上去把20个redis命令都熟悉和执行一遍就OK,这些命令足够redis集群的基本运维,涵盖了查看集群信息、hash slots分布、hash slots迁移等等操作。经常看到网上的博客说redis cluster缺点说需要依赖redis-trib.rb这个脚本才能维护,并且需要会ruby。我认为通过了解了20个redis命令,自己写脚本就可以实现redis集群的各种运维。
Redis集群缺点是:
(1)不支持多keys操作,通过查看官网文档可以了解,Redis集群主要担心多个大keys的merge会对性能带来较大的影响,所以最主要的问题是性能问题。但该操作也不能说的那么严格,如果两个keys在同一个Hash桶里,也可以进行多keys操作,但是为了避免问题,还是不要执行多keys操作。
(2)只能使用0号数据库
(3)还有一个缺点是缺乏大规模的线上使用,之前也有一些互联网的公司在用这个东西,但是有很多坑大家都没有测试出来,摸着石头过河,大家都不知道水有多深,不过随着redis cluster版本的更新,目前redis cluster已经在不少大互联网公司的推广使用。
上图是我模拟的主结点被kill掉之后redis集群的自我恢复,我想看内部大概需要多久能够提升。这个failover主要有两个关键点:第一是Cluster node的timeout时间,就是nodes之间在多少微秒后仍然获取不到节点的请求反馈。当一个master结点被kill掉以后,集群中节点在设定的超时时间内获取不到该结点的反馈,这个探测结点就会把该结点标记为fail,当半数以上的集群结点都选举同一个结点为fall down时,就会启动failover过程。第二就是投票选举新master的时间较短,如log中所示,整个切换用时不到一秒钟,这就是集群的高可用性。
接下来看一下大街网Redis Cluster的现状。
以下是大街网目前使用的Redis集群架构。特点如下:
(1)还是基于ZooKeeper做配置管理,并且ZK的配置只在2种情况下会被程序访问,一是程序启动时,初始化集群连接。二是我们迁移或者下线节点,修改了ZK中数据源的配置。目的就是做到集群对开发是透明的,也就是说开发数据库使用Redis集群时,只需要在程序中配置一个数据源就可以了。数据源中“种子节点“的配置也是可选的,比如一个6主6从的Redis集群,可以给它配4个结点也可以配6个结点,在程序启动的时候,它会取里面的数据源配置,检测种子结点。我们能够保证在至少一个种子节点可用的情况下,程序可以启动并正常使用(PS:程序启动时会报一些错误,但不影响使用)。
(2)中间层封装,目的是为了提供通用接口,原因是老的那套hash集群也是依赖接口,能够保证我推广Redis Cluster的时候,老的hash集群可以比较平滑的迁移到Redis Cluster上。二是基于通用的API,假如Jedis这个driver出现重大bug,我们可以对它进行替换,这样替换的成本也比较低。
(3)按业务来划分集群的,避免不同业务的相互影响。如果集群混用就可能出现一个人存的key比较大,或者执行了keys *等危险命令,导致整个集群的速度慢,会影响其它业务,所以我们根据之前的业务划分集群。
关于我们遇到的坑,第一点内存相关的设定
(1)最大内存没有设定,如果再加上keys又没有设定过期时间,这样随着业务的增长,redis就会一直占用内存,直到被linux oom kill掉。
(2)keys的过期时间,在功能上可以分为持久化和缓存集群。持久化集群代表keys只在redis中存,mysql中没有,这种keys不能设定过期时间。另一种就是缓存集群,这种需求的集群占95%以上,这些集群keys需要设定过期时间,就算缓存失效,当用户访问到这个keys的时候还会从mysql中取,同时set到缓存集群中。
(3)keys的过期策略,这个主要是redis使用到最大内存后如何处置的问题,我主要讲3个策略,一是volatile-lru,这个是设定keys过期时间缓存集群默认配置,redis会根据lru算法淘汰数据。二是allkeys-lru,对于一些非核心、并且程序员忘记给keys设定过期时间的redis配置,就是keys在set到redis集群时,redis会给keys标记一个时间(可以使用object idletime命令来查看keys的空转时间),当内存使用到上限时,redis根据lru算法来淘汰keys。三是:no-enviction策略,这个是redis集群的默认策略,就是永不淘汰keys,这样一单redis使用到内存上限,集群就无法写入了。
接下来可以看一下内存碎片率的问题,由于redis没有内存回收的策略。我们可以通过Redis_fragmentation_ratio这个参数可以反映出内存使用情况,该参数是操作系统分配内存(used_memory_rss)除以redis使用内存(used_memory)所得.
首先看内存碎片率大于1的情况。在redis使用过程中,由于一些keys的过期或者被主动清理,导致redis系统分配比实际使用的内存要多的多,呈现大于1的情况,要解决这个问题,可以通过重启Redis实例解决。
当Redis事例跟大量程序共用服务器时,内存碎片经常会出现小于1的情况。比如本来要存10G,但是系统分配的只有3G,此时,内存碎片就小于1,当Redis申请不到足够的内存,这样就会使用swap,导致性能急剧下降。解决方式:删除redis中的一些keys来空出内存,或者停掉一些程序后(停掉程序目的是节省内存,为该实例搭建从库而空出bgsave的内存),对该节点进行迁移。
核心参数主要有两个,
一是redis集群nodes探测的超时时间:系统默认的结点之间的超时时间是十五秒,我们设定的是5秒,当然,这可以根据自己不同的环境来设定,比如在一些虚拟机上,可以把这个参数设大。如果你们的网络足够稳定,并且你想让集群更快的发现出问题的node,并且尽快的执行salve提升,那就将该参数设小。
二是cluster-require-full-coverage参数,默认的值是yes,该参数配置成no的主要目的是在集群某些hash slots不可用的情况下,其他的hash slots仍然能够接受请求。举个例子如果集群里是3主3从,其中一组主从全部宕掉,其它两组主从依然能够接受读写请求,但这之中有个限制,整个集群必须有半数以上的结点配置是可用的,也就是说,如果3主3从的集群挂掉2主2从,这个集群就无法用了,因为不满足半数以上节点可用的情况。
另外,很多年轻的程序员在开发程序时,经常会check一下,查找程序里的keys是否已经set到线上Redis中,他们会连接到redis,执行keys *命令,该命令会阻塞线上请求。我们已经将这些危险命令在配置文件中进行了rename。对于上面的需求可以使用redis-cli的—scan –pattern来实现。
接下来探讨Redis连接周期性异常的问题,问题就是每半小时的大量的连接,并且不是长连接,一般程序连接redis都是长连接,出现这种问题一般可能被攻击或者某些程序的异常,必须及时的解决,我们最后通过tcpflow来抓取问题时间段的连接数据包情况,最终定位到具体的IP,并且找到原因。
如图所示出现了线上官客、www、job同时又大量的5XX报警,时间点发现是下午4:04到4:14左右,一般基础业务的同时抖动肯定跟底层DB或者cache有关。通过查看DB监控发现这几个DB实例性能稳定,然后将问题定位到缓存,因为跟职位相关,所以直接找职位相关的集群,进行问题排查。
通过查看job集群的Redis log,发现在出问题的时间段有2条aof写入异常:disk is busy?,通过查看源码发现,对于aof持久化,如果在2秒内aof文件无法写入,redis就不再接受任何请求,直到写入成功,在高的硬盘IO情况下,aof出现无法写入。通过查看服务器的IO负载情况,发现两个峰值,跟5XX的时间段也能匹配的上。这时问题的关键点就在于:是什么导致硬盘IO的峰值出现的。
第三步进行问题定位,因为该服务是redis专用服务器,能够导致如此高IO的操作,只有2种情况,一是aof rewrite,另一种情况就是bgsave来存rdb快照。进入redis数据目录,发现在出问题的时间段内,集群执行了rdb备份操作,从而导致了这两个时间段内的高IO。
解决以上问题的方法:(1)财大气粗的可以直接上SSD硬盘(2)将aof持久化集群跟缓存集群隔离,避免相互影响。
对于出现的问题,我对Redis持久化比较纠结,到底是用AOF还是rdb?为了解决困惑,我们先来看一下AOF和RDB的区别。
AOF的优点一:从启动起来就有序保存了所有写入操作,而且是在文件尾追加的,aof本身对IO的消耗并不高。
AOF优点二、误操作能及时恢复数据:如果有类似flushdb等操作,只需要修改下aof文件,剔除fulshdb操作,然后重启redis即可。
缺点是aof文件比较大,需要一段时间后进行aof rewrite。
RDB优点:RDB二进制文件非常紧凑,非常适合备份以及快速恢复。
RDB缺点是rdb只是某一时刻的内存快照,适合缓存集群的备份,不适合存储集群。
所以总结来说,根据需求选择合适的备份方式,缓存集群使用RDB备份,存储集群使用AOF。如果适当提高机器配置,因为redis主要是基于内存,aof阻塞问题也是能够解决的。
下面讲一下自动化,要做自动化之前必须有一个规范,目录,文件命名,keys使用,只要有了规范,自动化也不是非常难。二是自动化部署和配置,比如可能经常手动加内存,手误设定内存太小会导致写入问题。三是自动化监控,监控Redis性能,包括内存使用等。四是Redis自动迁移,五是集群扩容,六是自动化备份,七是分析包括slowlog分析、keys分布。
keys命名规范:命名之前应该想好要简单明确。一个好的命名对分析Redis节点的keys分布非常有帮助,比如命名一个job集群,可以用job_invite_*的方式来表示职位邀约的keys。这样做的好处是,当我需要对keys分布分析时,可以通过”_”来截取分析不同业务的keys。
Redis使用规范,是将我们遇到的坑加以规避。比如禁止将大量成员存储到一个hash key中,因为执行hgetall性能非常的差;禁止连接线上redis执行keys *dxl这种方式来过滤keys;keys建议设定过期时间,除非把redis当存储使用;合理使用Redis的数据类型:list、set、hash,因为合适的类型对性能和内存使用都能带来好处。
二是自动化部署Redis Cluster,创建集群的时候,只需要在配置表填写集群节点的相应信息,然后我们程序会调用配置信息自动建立集群。
其次集群配置,比如为集群扩展内存,之前线上Redis集群需添加内存是手工操作,在为最后一个结点设定内存时时,内存值少拷贝了一位,本来是几十G的东西弄成了几个G,redis可以设定成功,并不报错,但是程序访问会出问题,并且redis log中也会提示内存设置过小。解决方式,通过程序来自动设定,程序会检查线上redis已经使用的内存,跟DBA设定的内存进行比对后,只有DB设定的数值大才设定到线上redis。
自动化监控:Redis的命中率是所有人都关心的。可以写一个脚本,每十分钟通过info stats来采集计算,通过这个命中率就会反映出集群的使用情况。
自动化监控之内存使用—基于内存监控统计表,所有基于内存的报警都出自这个表,比如通过采的内存数据看出集群内存增长情况,是否是正常的增长,并且为内存自动添加提供数据支持。
自动化监控之连接监控:每十分钟抓链接请求情况,前面PPT提到的链接异常就是靠下面的统计表而来,对于异常的大量请求都会及时报警,然后DBA跟进分析,看是推广带来的连接还是被攻击。
自动化迁移工具:
在推广redis cluster的过程中,经常有程序员经常会说:这个单redis节点的keys必须全部给我导到集群里,否则我的程序会有各种问题。之前没有迁移工具,只能迁移那些缓存redis节点或者集群(因为这些集群keys在mysql中都有,他们只需要凌晨跑一遍全量数据,新redis集群中就有keys了),Redis集群推进比较缓慢。自从发现Redis-port这个工具之后,就不会产生由于无法迁移旧集群keys所无法迁移了。
Redis-port模拟了redis slave的角色。大致分为如图所示的七步。
1、rsync 2、fork进程 3、更新入buffer 4、dump rdb 5、fork进程exit 6、send rds 7、将buffer更新到集群
五是集群扩容
集群扩容主要分2种方式:
(1)如果之前集群分配的内存较少,现在集群所在的服务器内存也比较充裕,解决扩容可以直接扩大内存就搞定
(2)第二种方式是增加新结点,我的建议是直接增加1倍,因为这样避免了hash slots的零散,比如一个3主3从的redis集群扩展到换到6主6从,只需要把原来主节点上一半的hash slots分别分配到新加入的3个master上就OK,迁移程序好控制,slots分布也均匀。
增加新节点的扩容方式需要自己写脚本来实现,具体迁移的细节,redis官网上有,参考下面的连接:http://redis.io/commands/cluster-setslot
六是自动化备份,我们是根据配置表做的,只需要将配置表中:是否备份置为1即可,并且备份过程是自动化的。
性能分析之slow log,slowlog可以发现集群中执行时间长的命令,通过命令行:slowlog get 的输出是比较规整的,但如果需要存到统计表里还是需要花一些心思的,我们会将慢SQL统一整理分析后发给相应的负责人优化。
最后是keys分布,如果一个基础业务集群在1天内内存翻了一倍,谁能告诉我是哪些keys增加导致的?这时就需要keys分布工具来分析每一类keys的数量、占用内存大小等等,通过跟历史数量以及内存使用的对比可以找出问题的答案。我们采用RDB tools实现Keys分布。
今天的分享到此结束,希望我们的经验能给大家一定的帮助,谢谢大家!
关于DTCC
中国数据库技术大会(DTCC)是目前国内数据库与大数据领域最大规模的技术盛宴,于每年春季召开,迄今已成功举办了七届。大会云集了国内外顶尖专家,共同探讨MySQL、NoSQL、Oracle、缓存技术、云端数据库、智能数据平台、大数据安全、数据治理、大数据和开源、大数据创业、大数据深度学习等领域的前瞻性热点话题与技术,吸引IT人士参会5000余名,为数据库人群、大数据从业人员、广大互联网人士及行业相关人士提供了极具价值的交流平台。
redis
运维
数据库
cache
缓存
架构
hash
服务器
lvs
写下你的评论吧 !
吐个槽吧,看都看了
会员登录
|
用户注册
推荐阅读
python
Python 数据可视化实战指南
本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ...
[详细]
蜡笔小新 2024-11-13 06:03:30
grid
深入解析NoSQL数据库:键值对、文档、列式存储与图数据库的应用与特点
本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ...
[详细]
蜡笔小新 2024-11-09 14:47:28
grid
美团优选推荐系统架构师 L7/L8:算法与工程深度融合
美团优选推荐系统架构师 L7/L8:算法与工程深度融合 ...
[详细]
蜡笔小新 2024-11-05 19:10:28
search
综合实训 201521440015
Chinesepeople’publicsecurityuniversity网络对抗技术实验报告实验五综合渗透学生姓名常泽远年级15区队4指导教师高见信息技术与网络安全学院2018 ...
[详细]
蜡笔小新 2024-10-25 13:58:42
list
TypeScript: 泛型的力量与价值
本文探讨了 TypeScript 中泛型的重要性和应用场景,通过多个实例详细解析了泛型如何提升代码的复用性和类型安全性。 ...
[详细]
蜡笔小新 2024-11-15 12:12:42
int
面试题总结_2019年全网最热门的123个Java并发面试题总结
面试题总结_2019年全网最热门的123个Java并发面试题总结 ...
[详细]
蜡笔小新 2024-11-15 11:58:13
python
Java 网站开发指南
本文详细介绍了 Java 网站开发的相关资源和步骤,包括常用网站、开发环境和框架选择。 ...
[详细]
蜡笔小新 2024-11-14 22:39:58
erlang
RocketMQ在秒杀时的应用
目录一、RocketMQ是什么二、broker和nameserver2.1Broker2.2NameServer三、MQ在秒杀场景下的应用3.1利用MQ进行异步操作3. ...
[详细]
蜡笔小新 2024-11-14 12:27:39
int
高端存储技术演进与趋势
本文探讨了高端存储技术的发展趋势,包括松耦合架构、虚拟化、高性能、高安全性和智能化等方面。同时,分析了全闪存阵列和中端存储集群对高端存储市场的冲击,以及高端存储在不同应用场景中的发展趋势。 ...
[详细]
蜡笔小新 2024-11-14 11:58:22
int
网站访问全流程解析
本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ...
[详细]
蜡笔小新 2024-11-12 18:13:16
int
MySQL查询执行流程详解
MySQL的查询执行流程涉及多个关键组件,包括连接器、查询缓存、分析器和优化器。在服务层,连接器负责建立与客户端的连接,查询缓存用于存储和检索常用查询结果,以提高性能。分析器则解析SQL语句,生成语法树,而优化器负责选择最优的查询执行计划。这一流程确保了MySQL能够高效地处理各种复杂的查询请求。 ...
[详细]
蜡笔小新 2024-11-11 16:48:32
int
深入解析浏览器内核与版本的发展历程
浏览器作为我们日常不可或缺的软件工具,其背后的运作机制却鲜为人知。本文将深入探讨浏览器内核及其版本的演变历程,帮助读者更好地理解这一关键技术组件,揭示其内部运作的奥秘。 ...
[详细]
蜡笔小新 2024-11-11 13:34:37
erlang
Twitter架构深度解析与学习心得
作为140字符的开创者,Twitter看似简单却异常复杂。其简洁之处在于仅用140个字符就能实现信息的高效传播,甚至在多次全球性事件中超越传统媒体的速度。然而,为了支持2亿用户的高效使用,其背后的技术架构和系统设计则极为复杂,涉及高并发处理、数据存储和实时传输等多个技术挑战。 ...
[详细]
蜡笔小新 2024-10-31 17:58:20
int
LVS-DR数据包流向分析介绍
下文给大家带来LVS-DR数据包流向分析介绍,希望能够给大家在实际运用中带来一定的帮助,负载均衡涉及的东西比较多,理论也不多,网上有很多书籍, ...
[详细]
蜡笔小新 2024-10-21 20:17:54
int
【Linux332】LVS的DR配置详解(ipvsadm+arptables)
文章目录1.DR简 ...
[详细]
蜡笔小新 2024-10-21 18:38:08
范尼萧_659
这个家伙很懒,什么也没留下!
Tags | 热门标签
erlang
solr
plugins
actionscrip
command
list
nodejs
usb
iostream
split
yaml
foreach
node.js
future
tags
integer
require
search
blob
heatmap
dagger
bash
grid
jar
object
copy
frameworks
int
less
python
RankList | 热门文章
1
论纸老虎
2
恒生银行:RPA助力企业客户信贷申请、五级分类及年度审阅
3
将采用多屏联动设计,电咖汽车张海亮谈推出高端ENOVATE背后逻辑|全球未来出行大会
4
医疗AI如何证明自己五年后的价值?
5
数字图像处理编成入门——第二章图象的几何变换
6
MFC迷宫程序
7
腾讯云&光环大数据开发者大会
8
GSM Hack(手机信号劫持)
9
相关性分析都有那些算法
10
求链表的第一个公共节点问题(好未来笔试题)
11
以后社会都是无人驾驶,无人售货,无人操作,那人都干嘛去?
12
智慧城市就要来了,你期待吗?
13
深度学习与其他AI算法
14
关于Floyd的打印路径的个人总结
15
[转载]AdaBoost算法
PHP1.CN | 中国最专业的PHP中文社区 |
DevBox开发工具箱
|
json解析格式化
|
PHP资讯
|
PHP教程
|
数据库技术
|
服务器技术
|
前端开发技术
|
PHP框架
|
开发工具
|
在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved |
京公网安备 11010802041100号
|
京ICP备19059560号-4
| PHP1.CN 第一PHP社区 版权所有