技术标签: 最佳实践 平台 缓存 分布式缓存 分布式缓存平台方案
目录
以redis为底层存储设施,建设高性能、高可用、可扩展、易于运维和管理的缓存平台,以灵活满足各种缓存应用场景。
redis提供的这些特性,便于达成我们的目标。在此之上,按照实际的业务需求,进行扩展和辅助工具的开发,建立完善的统一管理平台。
Redis server pool
独立部署一系列redis server或者将现有已经部署的redis server纳入管理,形成逻辑上统一的缓存资源池。
Gather servers
部署一系列分布式采集应用节点,分别对所有的redis server和redis proxy进行信息采集,存储的同时发送到实时监控服务。
监控服务
对采集传输的数据进行实时分析,使用预定义的一系列规则进行报警。
Stat/Analysis服务
部署一系列分布式统计应用节点,分别对原始采集数据进行准实时统计汇总并存储。原始采集信息统计完毕之后删除。集中存储所有的统计结果。统计节点本地系统同时存储本节点负责的统计结果,以便展现。
Config/Meta/Manage Servers
负责将变动的集群信息(节点拓扑、路由和读写策略等)push到相应的proxy。负责提供配置和元信息服务,以便应用端的Client SDK来polling变更。负责控制各个物理机上的Agent,对redis实例进行部署管理和配置文件同步。
Agent
部署在缓存资源池中各个物理机上,负责本机redis实例的部署和配置文件同步。
Client SDK
Client SDK为应用提供操作redis集群数据的API。利用polling到的集群配置元信息(节点拓扑、路由和读写策略等),访问后端的redis server节点。SDK负责监控配置信息变更(比如故障切换、服务节点迁移等),动态重启底层的连接池。对应用透明。
Proxy
Client SDK相对比较复杂,而且需要适应多种开发语言。因此可以把Client SDK的功能后移到中间的proxy层,通过proxy来对应用屏蔽这些复杂性。Redis proxy是实现了redis 协议的无状态的server,无论何种语言的redis客户端都可访问它。应用通过load balance设备来访问后端的多个proxy server。
管理平台
包括对以上各个组件的统一管理,以及一系列运维管理工具。
缓存平台对外提供的协议或接口,除了本身就支持的redis协议外,还可通过proxy中间件提供memcached、REST等协议。
虽然proxy方式比native直连方式性能要差,但也有优势:
在性能完全满足业务需求的场景,可考虑使用proxy。否则,可使用专用的redis客户端SDK。
底层支持:Master/Slave复制、AOF日志持久、RDB快照持久
扩展:jd-redis-dumper。
3.1.1、Master/Slave复制
典型部署场景
在运营经验上,链式复制优于1->n的复制方式。
通过跨机房复制,提高本地读性能。
复制机制
redis采用异步方式保证最大的复制效率,同时对master性能影响最小。不支持同步方式,而是通过复制的可靠性配置来保证数据的安全。
复制的可靠性(延时保证)
min-slaves-to-write <number of slaves> #最少需要存在slave数量才能允许写
min-slaves-max-lag <number of seconds> #slave落后master最大的秒数
一致性保证
slave-read-only true
3.1.2、AOF
将redis实例所有的写操作命令以redis协议文本格式追加到本机日志文件,通过replay日志来恢复数据。
可靠性保证
appendfsync always:每次追加日志同时都执行fsync持久到介质,最可靠,性能最差。
appendfsync no:只追加,不执行fsync。由操作系统保证高速缓存持久到介质,性能最高,可靠性依赖操作系统,有可能丢失尚未持久到介质的更新数据。
appendfsync everysec:每秒执行一次fsync,性能居中,最坏丢失的更新数据不超过2秒。
AOF整理
自动:auto-aof-rewrite-percentage <percent>,自动重新AOF以减少文件大小。
手动/定时:bgrewriteaof
3.1.3、RDB快照
将redis实例内存数据完整的持久到本机二进制快照文件,通过load快照文件恢复数据。
可靠性保证
stop-writes-on-bgsave-error no
策略
自动:save <after seconds> <if changes number>
手动/定期:bgsave
3.1.4、jd-redis-dumper
实现redis的复制协议的中间件。在跨机柜/交换机或者跨机房的主机上,将一个或多个实例的数据复制到jd-redis-dumper所在机器,并以AOF或RDB方式存储。通过远端的AOF和RDB来恢复数据。数据安全和Master/Slave一样,但是节约了内存资源,恢复速度要慢。
3.1.5、基础设施小结
从数据安全等级、故障恢复速度综合来看,优先级如下:
Master/Slave复制 > jd-redis-dumper > AOF > 快照
实践:
3.2.1、分布式采集器
zookeeper协调的多个采集器,定期收集所有集群和实例的info/config信息供准实时分析,同时发现故障实例,报告给故障决策组件。
3.2.2、存活报警策略
实例不存活报告次数,在某个时间范围内,到达指定值,则进行报警。
3.2.3、官方的Sentinel
分布式的故障检测组件,实践中不合适管理大量的集群。
当发生报警后,通过人工或者故障决策组件自动确认后,开始进行故障切换。只有AOF或者RDB的,通过Agent重启实例恢复数据。有Slave的,将Slave提升为主。
通过在本机或跨机部署多个实例形成一个逻辑上的集群,提高整体性能,减少单点故障。每个实例作为逻辑集群的一个分片(Sharding),承担部分数据的存储和读写请求。每个分片还可以配置对应的Slave,形成一个高可用分布式的集群方案。client/proxy按照key通过特定路由算法(比如一致性hash)请求特定的分片。
目前redis的最佳实践是pre-sharding + clientside routing来做分布式方案,其cluster方案还不成熟。
pre-sharding,创建足够多的分片实例,部署在有限的几台物理机上。当缓存增长时,可通过扩大物理机内存,或将实例迁移到另外的物理机上,并扩大每个实例的最大内存设置,来达到整体扩容的目的。
故障切换流程同样适用于实例迁移。
当一个分片实例的内存容量增长到已经不合适放在一台物理机上时,势必要进行分片数量的增加。涉及到缓存数据的重新分布,可通过jd-redis-bridge来做。
预先规划,合理配置。按照业务缓存数据增长量来提前规划分片数量,权衡成本和收益,配合垂直扩展和水平扩展来适应缓存的增长。
实践:
屏蔽或修改危险命令:
直连方式
ClientSDK通过token获取相应的集群拓扑配置。
Proxy方式
Redis的auth协议被用作client的token,proxy与后端server不需要认证。
为redis实例配置passwd
缓存管理平台中各个组件的运行情况的监控。
文章浏览阅读255次。2019独角兽企业重金招聘Python工程师标准>>> ..._modis和aster lst误差
文章浏览阅读46次。封装Encapsulation如下代码,这就算是封装了(function (windows, undefined) { var i = 0;//相对外部环境来说,这里的i就算是封装了})(window, undefined);继承Inheritance(function (windows, undefined) { //父类 ...
文章浏览阅读186次。异常处理汇总-服 务 器http://www.cnblogs.com/dunitian/p/4522983.html异常处理汇总-数据库系列 http://www.cnblogs.com/dunitian/p/4522990.html情况不唯一,这边只能当参考,大致就是这么几种解决思路child process failed, exit..._forked process: 68247 error: child process failed, exited with error number
文章浏览阅读285次。开发环境:Hadoop+HBASE+Phoenix+flum+kafka+spark+MySQL默认配置好了Hadoop的开发环境,并且已经安装好HBASE等组件。下面通过一个简单的案例进行整合:这是整个工作的流程图:第一步:获取数据源 由于外部埋点获取资源较为繁琐,因此,自己写了个自动生成类似数据代码:import org.apache.logging.l..._spark存储到hbase数据库
文章浏览阅读8.4k次,点赞8次,收藏41次。文章目录14、Three.js 加载外部模型文件14.1 Three.js 数据结构、导入导出Threejs导出模型信息自定义模型加载器文件加载Three.js导出的模型数据14.2 加载 stl 文件并解析stl文件数据结构通过STLLoader.js加载.stl文件使用点模型渲染STL文件14.3 加载obj文件(几何体、材质、贴图)只加载obj文件同时加载obj文件和mtl文件obj包含多个网格模型模型纹理贴图导出.obj和.mtl的名称、路径问题.obj文件不包含信息14.4 加载FBX并解析骨骼动_threejs 绝对路径加载文件
文章浏览阅读314次。navicat for mysql 链接时报错:1251-Client does not support authentication protocol requested by server;consider upgrading MySQL client主要原因是mysql服务器要求的认证插件版本与客户端不一致造成的。打开mysql命令行输入如下命令查看,系统用户对应的认证插件解决方法:..._navicat for mysql client does not support
文章浏览阅读143次。压缩包 : b0cc066cf6a29de6773a55cd42e08.zip 列表CuraEngine_vs-master/CuraEngine_vs-master/ALL_BUILD.vcxprojCuraEngine_vs-master/Arcus.dllCuraEngine_vs-master/Cura.pb.ccCuraEngine_vs-master/Cura.pb.hCuraEngi..._curaengine-vs2017
文章浏览阅读2.7k次。整个过程只有两个步骤:发起支付请求和响应支付结果首先是Web.xml[html] view plaincopyprint?xml version="1.0" encoding="UTF-8"?> web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" _易宝支付 交易网址 csdn
文章浏览阅读4.9k次,点赞10次,收藏33次。1 目的学习使用深度学习模型对代码进行系统性的分析2 运行前准备2.1 阅读readme.md 查看整个工程运转的流程,整体分三步: 第一步:生成切片文件 第二步:数据预处理 第三步:输入数据,利用深度学习模型进行训练 查看所需的环境(注意:虽然readme.md中提到的python环境为3.6,但是joern-0.3.1..._sysevr训练教程
文章浏览阅读4k次,点赞2次,收藏6次。Usercontrol可以将已有的控件重新组合为新的控件,本文将会说明如何实现前台代码设置Usercontol的属性以及事件。首先,我们先新建一个Usercontrol,命名为:UCUC中,有一个Label和一个Button。UC的 LabelText 属性与 Label 的 Content 绑定在一起。UC的BTNClick属性与Button的Click事件关联在一起。xam..._wpf用户控件事件
文章浏览阅读1w次,点赞4次,收藏27次。#include<stdio.h>int main(){ int i=0,n,score=0,sum=0,ave=0,a[100]; printf("请输入学生人数\n"); scanf("%d",&n); while(1) { printf("请输入%d学生成绩\n",i+1); scanf("%d",&a[i]); if(a[i]<0) break; i++; } for(i=0;i<n;i++) { ._编程从键盘输入若干个学生的成绩,输入负数时表示输入结束,输出平均成绩和低于平均
文章浏览阅读137次。这篇文章主要介绍了python从sqlite读取并显示数据的方法,涉及Python操作SQLite数据库的读取及显示相关技巧,需要的朋友可以参考下importcgi,os,sysimportsqlite3asdbconn=db.connect('test.db')cursor=conn.cursor()conn.row_factory=db.Rowcursor.execut..._python sqlite 读取