优酷土豆的Redis服务平台化之路(优酷土豆是什么软件)
mhr18 2024-10-23 11:37 27 浏览 0 评论
1、Redis架构的方案经历阶段
1.1. 客户端分片
客户端分片:
优点
不依赖于第三方中间件,实现方法和代码自己掌控,可随时调整
这种分片机制的性能比代理式更好(少了一个中间分发环节)
可控的分发请求,分发压力落在客户端,无服务器压力增加
缺点
不能平滑的水平扩展节点,扩容/缩容时,必须手动调整分片程序
出现故障,不能自动转移,运维性很差
客户端得自己维护一套路由算法
升级复杂
1.2. Twemproxy
Twemproxy:
优点
运维成本低。业务方不用关心后端Redis实例,跟操作Redis一样
Proxy 的逻辑和存储的逻辑是隔离的
缺点
代理层多了一次转发,性能有所损耗
进行扩容/缩容时候,部分数据可能会失效,需要手动进行迁移,对运维要求较高,而且难以做到平滑的扩缩容
出现故障,不能自动转移,运维性很差
升级复杂
1.3. Redis Cluster
Redis Cluster:
优点
无中心节点
数据按照Slot存储分布在多个Redis实例上
平滑的进行扩容/缩容节点
自动故障转移(节点之间通过Gossip协议交换状态信息,进行投票机制完成Slave到Master角色的提升)
降低运维成本,提高了系统的可扩展性和高可用性
缺点
严重依赖外部Redis-Trib
缺乏监控管理
需要依赖Smart Client(连接维护, 缓存路由表, MultiOp和Pipeline支持)
Failover节点的检测过慢,不如“中心节点ZooKeeper”及时
Gossip消息的开销
无法根据统计区分冷热数据
Slave“冷备”,不能缓解读压力
1.4. Proxy+Redis Cluster
Smart Client vs Proxy:
优点
Smart Client:
a. 相比于使用代理,减少了一层网络传输的消耗,效率较高。
b. 不依赖于第三方中间件,实现方法和代码自己掌控,可随时调整。
Proxy:
a. 提供一套HTTP Restful接口,隔离底层存储。对客户端完全透明,跨语言调用。
b. 升级维护较为容易,维护Redis Cluster,只需要平滑升级Proxy。
c. 层次化存储,底层存储做冷热异构存储。
d. 权限控制,Proxy可以通过秘钥控制白名单,把一些不合法的请求都过滤掉。并且也可以控制用户请求的超大Value进行控制,和过滤。
e. 安全性,可以屏蔽掉一些危险命令,比如Keys、Save、Flush All等。
f. 容量控制,根据不同用户容量申请进行容量限制。
g. 资源逻辑隔离,根据不同用户的Key加上前缀,来进行资源隔离。
h. 监控埋点,对于不同的接口进行埋点监控等信息。
缺点
Smart Client:
a. 客户端的不成熟,影响应用的稳定性,提高开发难度。
b. MultiOp和Pipeline支持有限。
c. 连接维护,Smart客户端对连接到集群中每个结点Socket的维护。
Proxy:
a. 代理层多了一次转发,性能有所损耗。
b.进行扩容/缩容时候对运维要求较高,而且难以做到平滑的扩缩容。
2、为什么选择Nginx开发Proxy
1.单Master多Work模式,每个Work跟Redis一样都是单进程单线程模式,并且都是基
于Epoll事件驱动的模式。
2.Nginx采用了异步非阻塞的方式来处理请求,高效的异步框架。
3.内存占用少,有自己的一套内存池管理方式,。将大量小内存的申请聚集到一块,能够比Malloc 更快。减少内存碎片,防止内存泄漏。减少内存管理复杂度。
4. 为了提高Nginx的访问速度,Nginx使用了自己的一套连接池。
5. 最重要的是支持自定义模块开发。
6. 业界内,对于Nginx,Redis的口碑可称得上两大神器。性能也就不用说了。
3、Proxy+Redis Cluster介绍
3.1 Proxy+Redis Cluster架构方案介绍
1. 用户在ACL平台申请集群资源,如果申请成功返回秘钥信息。
2. 用户请求接口必须包含申请的秘钥信息,请求至LVS服务器。
3. LVS根据负载均衡策略将请求转发至Nginx Proxy。
4. Nginx Proxy首先会获取秘钥信息,然后根据秘钥信息去ACL服务上获取集群的种子信息。(种子信息是集群内任意几台IP:PORT节点)
然后把秘钥信息和对应的集群种子信息缓存起来。并且第一次访问会根据种子IP:PORT获取集群Slot对应节点的Mapping路由信息,进行缓存起来。最后根据Key计算SlotId,从缓存路由找到节点信息。
5. 把相应的K/V信息发送到对应的Redis节点上。
6. Nginx Proxy定时(60s)上报请求接口埋点的QPS,RT,Err等信息到Open-Falcon平台。
7. Redis Cluster定时(60s)上报集群相关指标的信息到Open-Falcon平台。
3.2 Nginx Proxy功能介绍
目前支持的功能:
HTTP Restful接口:
解析用户Post过来的数据, 并且构建Redis协议。客户端不需要开发Smart Client, 对客户端完全透明、跨语言调用
权限控制:
根据用户Post数据获取AppKey,Uri, 然后去ACL Service服务里面进行认证。如果认证通过,会给用户返回相应的集群种子IP,以及相应的过期时间限制等信息
限制数据大小:
获取用户Post过来的数据,对Key,Value长度进行限制,避免产生超大的Key,Value,打满网卡、阻塞Proxy
数据压缩/解压:
如果是写请求,对Value进行压缩(Snappy),然后在把压缩后的数据存储到Redis Cluster。
如果是读请求,把Value从Redis Cluster读出来,然后对Value进行解压,最后响应给用户。
缓存路由信息:
维护路由信息,Slot对应的节点的Mapping信息
结果聚合:
MultiOp支持
批量指令支持(Pipeline/Redis+Lua+EVALSHA进行批量指令执行)
资源逻辑隔离:
根据用户Post数据获取该用户申请的NameSpace,然后以NameSpace作为该用户请求Key的前缀,从而达到不同用户的不同NameSpace,进行逻辑资源隔离
重试策略:
针对后端Redis节点出现Moved,Ask,Err,TimeOut等进行重试,重试次数可配置
连接池:
维护用户请求的长连接,维护后端服务器的长连接
配额管理:
根据用户的前缀(NameSpace), 定时的去抓取RANDOMKEY,根据一定的比率,估算出不同用户的容量大小值,然后在对用户的配额进行限制管理
过载保护:
通过在Nginx Proxy Limit模块进行限速,超过集群的承载能力,进行过载保护。从而保证部分用户可用,不至于压垮服务器
监控管理:
Nginx Proxy接入了Open-Falcon对系统级别,应用级别,业务级别进行监控和告警
例如: 接口的QPS,RT,ERR等进行采集监控,并且展示到DashBoard上
告警阈值的设置非常灵活,配置化
待开发的功能列表:
层次化存储:
利用Nginx Proxy共享内存定制化开发一套LRU本地缓存实现,从而减少网络请求
冷数据Swap到慢存储,从而实现冷热异构存储
主动Failover节点:
由于Redis Cluster是通过Gossip通信, 超过半数以上Master节点通信(cluster-node-timeout)认为当前Master节点宕机,才真的确认该节点宕机。判断节点宕机时间过长,在Proxy层加入Raft算法,加快失效节点判定,主动Failover
3.3 Nginx Proxy性能优化
3.3.1 批量接口优化方案
1. 子请求变为协程
案例:
用户需求调用批量接口mget(50Key)要求性能高,吞吐高,响应快。
问题:
由于最早用的Nginx Subrequest来做批量接口请求的处理,性能一直不高,CPU利用率也不高,QPS提不起来。通过火焰图观察分析子请求开销比较大。
解决方案:
子请求效率较低,因为它需要重新从Server Rewrite开始走一遍Request处理的PHASE。并且子请求共享父请求的内存池,子请求同时并发度过大,导致内存较高。
协程轻量级的线程,占用内存少。经过调研和测试,单机一两百万个协程是没有问题的,
并且性能也很高。
优化前:
a) 用户请求mget(k1,k2)到Proxy
b) Proxy根据k1,k2分别发起子请求subrequest1,subrequest2
c) 子请求根据key计算slotid,然后去缓存路由表查找节点
d) 子请求请求Redis Cluster的相关节点,然后响应返回给Proxy
e) Proxy会合并所有的子请求返回的结果,然后进行解析包装返回给用户
优化后:
a) 用户请求mget(k1,k2)到Proxy
b) Proxy根据k1,k2分别计算slotid, 然后去缓存路由表查找节点
c) Proxy发起多个协程coroutine1, coroutine2并发的请求Redis Cluster的相关节点
d) Proxy会合并多个协程返回的结果,然后进行解析包装返回给用户
2. 合并相同槽,批量执行指令,减少网络开销
案例:
用户需求调用批量接口mget(50key)要求性能高,吞吐高,响应快。
问题:
经过上面协程的方式进行优化后,发现批量接口性能还是提升不够高。通过火焰图观察分析网络开销比较大。
解决方案:
因为在Redis Cluster中,批量执行的key必须在同一个slotid。所以,我们可以合并相同slotid的key做为一次请求。然后利用Pipeline/Lua+EVALSHA批量执行命令来减少网络开销,提高性能。
优化前:
a) 用户请求mget(k1,k2,k3,k4) 到Proxy。
b) Proxy会解析请求串,然后计算k1,k2,k3,k4所对应的slotid。
c) Proxy会根据slotid去路由缓存中找到后端服务器的节点,并发的发起多个请求到后端服务器。
d) 后端服务器返回结果给Proxy,然后Proxy进行解析获取key对应的value。
e) Proxy把key,value对应数据包装返回给用户。
优化后:
a) 用户请求mget(k1,k2,k3,k4) 到Proxy。
b) Proxy会解析请求串,然后计算k1,k2,k3,k4所对应的slotid,然后把相同的slotid进行合并为一次Pipeline请求。
c) Proxy会根据slotid去路由缓存中找到后端服务器的节点,并发的发起多个请求到后端服务器。
d) 后端服务器返回结果给Proxy,然后Proxy进行解析获取key对应的value。
e) Proxy把key,value对应数据包装返回给用户。
3. 对后端并发度的控制
案例:
当用户调用批量接口请求mset,如果k数量几百个甚至几千个时,会导致Proxy瞬间同时发起几百甚至几千个协程同时去访问后端服务器Redis Cluster。
问题:
Redis Cluster同时并发请求的协程过多,会导致连接数瞬间会很大,甚至超过上限,CPU,连接数忽高忽低,对集群造成不稳定。
解决方案:
单个批量请求对后端适当控制并发度进行分组并发请求,反向有利于性能提升,避免超过Redis Cluster连接数,同时Redis Cluster 波动也会小很多,更加的平滑。
优化前:
a) 用户请求批量接口mset(200个key)。(这里先忽略合并相同槽的逻辑)
b) Proxy会解析这200个key,会同时发起200个协程请求并发的去请求Redis Cluster。
c) Proxy等待所有协程请求完成,然后合并所有协程请求的响应结果,进行解析,包装返回给用户。
优化后:
a) 用户请求批量接口mset(200个key)。 (这里先忽略合并相同槽的逻辑)
b) Proxy会解析这200个key,进行分组。100个key为一组,分批次进行并发请求。
c) Proxy先同时发起第一组100个协程(coroutine1, coroutine100)请求并发的去请求Redis Cluster。
d) Proxy等待所有协程请求完成,然后合并所有协程请求的响应结果。
e) Proxy然后同时发起第二组100个协程(coroutine101, coroutine200)请求并发的去请求Redis Cluster。
f) Proxy等待所有协程请求完成,然后合并所有协程请求的响应结果。
g) Proxy把所有协程响应的结果进行解析,包装,返回给用户。
4.单Work分散到多Work
案例:
当用户调用批量接口请求mset,如果k数量几百个甚至几千个时,会导致Proxy瞬间同时发起几百甚至几千个协程同时去访问后端服务器Redis Cluster。
问题:
由于Nginx的框架模型是单进程单线程, 所以Proxy发起的协程都会在一个Work上,这样如果发起的协程请求过多就会导致单Work CPU打满,导致Nginx 的每个Work CPU使用率非常不均,内存持续暴涨的情况。(nginx 的内存池只能提前释放大块,不会提前释放小块)
解决方案:
增加一层缓冲层代理,把请求的数据进行拆分为多份,然后每份发起请求,控制并发度,在转发给Proxy层,避免单个较大的批量请求打满单Work,从而达到分散多Work,达到Nginx 多个Wrok CPU使用率均衡。
优化前:
a) 用户请求批量接口mset(200个key)。(这里先忽略合并相同槽的逻辑)
b) Proxy会解析这200个key,会同时发起200个协程请求并发的去请求Redis Cluster。
c) Proxy等待所有协程请求完成,然后合并所有协程请求的响应结果,进行解析,包装返回给用户。
优化后:
a) 用户请求批量接口mset(200个key)。(这里先忽略合并相同槽的key的逻辑)
b) Proxy会解析这200个key,然后进行拆分分组以此来控制并发度。
c) Proxy会根据划分好的组进行一组一组的发起请求。
d) Proxy等待所有请求完成,然后合并所有协程请求的响应结果,进行解析,包装返回给用户。
总结,经过上面一系列优化,我们可以来看看针对批量接口mset(50个k/v)性能对比图,Nginx Proxy的响应时间比Java版本的响应时间快了5倍多。
Java版本:
3.3.2 网卡软中断优化
irqbalance根据系统中断负载的情况,自动迁移中断保持中断的平衡。但是在实时系统中会导致中断自动漂移,对性能造成不稳定因素,在高性能的场合建议关闭。
1、首先关闭网卡软中断
service irqbalance stop
service cpuspeed stop
2、查看网卡是队列
grep eth /proc/interrupts | awk '{print $1, $NF}'
77: eth0
78: eth0-TxRx-0
79: eth0-TxRx-1
80: eth0-TxRx-2
81: eth0-TxRx-3
82: eth0-TxRx-4
83: eth0-TxRx-5
84: eth0-TxRx-6
85: eth0-TxRx-7
3、绑定网卡软中断到CPU0-2号上
(注意这里的echo 是十六进制)
echo "1" > /proc/irq/78/smp_affinity
echo "1" > /proc/irq/79/smp_affinity
echo "2" > /proc/irq/80/smp_affinity
echo "2" > /proc/irq/81/smp_affinity
echo "2" > /proc/irq/82/smp_affinity
echo "4" > /proc/irq/83/smp_affinity
echo "4" > /proc/irq/84/smp_affinity
echo "4" > /proc/irq/85/smp_affinity
3.3.3 绑定进程到指定的CPU
绑定nginx或者redis的pid到cpu3-cpu10上:
taskset -cp 3 1900
taskset -cp 4 1901
taskset -cp 5 1902
taskset -cp 6 1903
taskset -cp 7 1904
taskset -cp 8 1905
taskset -cp 9 1902
taskset -cp 10 1902
或者通过Nginx Proxy配置:
worker_cpu_affinity 绑定CPU亲缘性
3.3.4 性能优化神器火焰图
3.4 Redis Cluster运维
3.4.1 运维功能
1. 创建集群
2. 集群扩容/缩容
3. 节点宕机
4. 集群升级
5. 迁移数据
6. 副本迁移
7. 手动failover
8. 手动rebalance
以上相关运维功能,目前是通过脚本配置化一键式操作,依赖于官方的redis-rebalance.rb进行扩展开发。运维非常方便快捷。
3.5 性能测试报告
3.5.1 测试环境
软件:
Jmeter
Nginx Proxy(24核)
Redis集群(4 Master,4 Slave)
测试Key(100000)
硬件:
OS: Centos6.6
CPU:24核
带宽:千兆
内存:62G
测试结果:场景:普通K/V
QPS:18W左右
RT: 99都在10ms以内
CPU:Nginx Proxy CPU在50%左右
4、监控告警
4.1 系统级别
通过Open-Falcon Agent采集服务器的CPU、内存、网卡流量、网络连接、磁盘等信息。
4.2 应用级别
通过Open-Falcon Plugin采集Nginx/Redis进程级别的CPU,内存,Pid等信息。
4.3 业务级别
通过在Proxy里面埋点监控业务接口QPS,RT(50%,99%,999%),请求流量,错误次数等信息,定时的上报给Open-Falcon。
通过Open-Falcon Plugin采集Redis Cluster集群信息,QPS,连接数等相关指标指标信息。
相关推荐
- Docker安装详细步骤及相关环境安装配置
-
最近自己在虚拟机上搭建一个docker,将项目运行在虚拟机中。需要提前准备的工具,FinallShell(远程链接工具),VM(虚拟机-配置网络)、CentOS7(Linux操作系统-在虚拟机上安装)...
- Linux下安装常用软件都有哪些?做了一个汇总列表,你看还缺啥?
-
1.安装列表MySQL5.7.11Java1.8ApacheMaven3.6+tomcat8.5gitRedisNginxpythondocker2.安装mysql1.拷贝mysql安装文件到...
- Nginx安装和使用指南详细讲解(nginx1.20安装)
-
Nginx安装和使用指南安装1.检查并安装所需的依赖软件1).gcc:nginx编译依赖gcc环境安装命令:yuminstallgcc-c++2).pcre:(PerlCompatibleRe...
- docker之安装部署Harbor(docker安装hacs)
-
在现代软件开发和部署环境中,Harbor作为一个企业级的容器镜像仓库,提供了高效、安全的镜像管理解决方案。通过Docker部署Harbor,可以轻松构建私有镜像仓库,满足企业对镜像存储、管理和安全性...
- 成功安装 Magento2.4.3最新版教程「技术干货」
-
外贸独立站设计公司xingbell.com经过多次的反复实验,最新版的magento2.4.3在oneinstack的环境下的详细安装教程如下:一.vps系统:LinuxCentOS7.7.19...
- 【Linux】——从0到1的学习,让你熟练掌握,带你玩转Linu
-
学习Linux并掌握Java环境配置及SpringBoot项目部署是一个系统化的过程,以下是从零开始的详细指南,帮助你逐步掌握这些技能。一、Linux基础入门1.安装Linux系统选择发行版:推荐...
- cent6.5安装gitlab-ce最新版本-11.8.2并配置邮件服务
-
cent6.5安装gitlab-ce最新版本-11.8.2并配置邮件服务(yum选择的,时间不同,版本不同)如果对运维课程感兴趣,可以在b站上搜索我的账号:运维实战课程,可以关注我,学习更多免费的运...
- 时隔三月,参加2020秋招散招,终拿字节跳动后端开发意向书.
-
3个月前头条正式批笔试4道编程题只AC了2道,然后被刷了做了200多道还是太菜了,本来对字节不抱太大希望,毕竟后台竞争太大,而且字节招客户端开发比较多。后来看到有散招免笔试,抱着试一试的心态投了,然而...
- Redisson:Java程序员手中的“魔法锁”
-
Redisson:Java程序员手中的“魔法锁”在这个万物互联的时代,分布式系统已经成为主流。然而,随着系统的扩展,共享资源的争夺成为了一个棘手的问题。就比如你想在淘宝“秒杀”一款商品,却发现抢的人太...
- 【线上故障复盘】RPC 线程池被打满,1024个线程居然不够用?
-
1.故障背景昨天晚上,我刚到家里打开公司群,就看见群里有人讨论:线上环境出现大量RPC请求报错,异常原因:被线程池拒绝。虽然异常量很大,但是异常服务非核心服务,属于系统旁路,服务于数据核对任务,即使...
- 小红书取消大小周,有人不高兴了!
-
小红书宣布五一节假日之后,取消大小周,恢复为正常的双休,乍一看工作时长变少,按道理来说大家应该都会很开心,毕竟上班时间缩短了,但是还是有一些小红书的朋友高兴不起来,心情很复杂。因为没有了大小周,以前...
- 延迟任务的多种实现方案(延迟机制)
-
场景订单超时自动取消:延迟任务典型的使用场景是订单超时自动取消。功能精确的时间控制:延时任务的时间控制要尽量准确。可靠性:延时任务的处理要是可靠的,确保所有任务最终都能被执行。这通常要求延时任务的方案...
- 百度java面试真题(java面试题下载)
-
1、SpingBoot也有定时任务?是什么注解?在SpringBoot中使用定时任务主要有两种不同的方式,一个就是使用Spring中的@Scheduled注解,另一个则是使用第三方框架Q...
- 回归基础:访问 Kubernetes Pod(concurrent.futures访问数据库)
-
Kubernetes是一头巨大的野兽。在它开始有用之前,您需要了解许多概念。在这里,学习几种访问集群外pod的方法。Kubernetes是一头巨大的野兽。在它开始有用之前,您需要了解许多不同的...
- Spring 缓存神器 @Cacheable:3 分钟学会优化高频数据访问
-
在互联网应用中,高频数据查询(如商品详情、用户信息)往往成为性能瓶颈。每次请求都触发数据库查询,不仅增加服务器压力,还会导致响应延迟。Spring框架提供的@Cacheable注解,就像给方法加了一...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Docker安装详细步骤及相关环境安装配置
- Linux下安装常用软件都有哪些?做了一个汇总列表,你看还缺啥?
- Nginx安装和使用指南详细讲解(nginx1.20安装)
- docker之安装部署Harbor(docker安装hacs)
- 成功安装 Magento2.4.3最新版教程「技术干货」
- 【Linux】——从0到1的学习,让你熟练掌握,带你玩转Linu
- cent6.5安装gitlab-ce最新版本-11.8.2并配置邮件服务
- 时隔三月,参加2020秋招散招,终拿字节跳动后端开发意向书.
- Redisson:Java程序员手中的“魔法锁”
- 【线上故障复盘】RPC 线程池被打满,1024个线程居然不够用?
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)