CYQ.Data 对于分布式缓存Redis、MemCache高可用的改进及性能测试
背景:
随着.NET Core 在 Linux 下的热动,相信动不动就要分布式或集群的应用的需求,会慢慢火起来。
所以这段时间一直在研究和思考分布式集群的问题,同时也在思考把几个框架的思维相对提升到这个Level。
最近大力重构了框架两个点:一个是分布式缓存,一个是数据库主从备。
今天,先分享分布式缓存的改进的两个点:
1、高可用:能动态增加或减少Redis、MemCache的实例,而不影响程序。
2、高性能:保障在高并发下的稳定性及性能。
1、Redis、MemCache 分布式下的高可用。
要实现分布下应用下的高可用,就两种方法:
1、建立集群,内部调度,对外只提供一个接口。
优点:对所有不同的开发语言和客户端都通用。
缺点:建立相对复杂,需要有专业的运维知识,而且对于提供出口的服务器,也要再做一次主备,整体硬件成本高。
2、由客户端进行调度。
优点:比较简单,不需要专业知识,上千个Redis实例,随时就动起来。
缺点:如果项目有混合多种后端语言开发的,还得有多种客户端实现。
而 CYQ.Data 就是.NET Core 下集成了操作Redis的一种客户端实现。
下面来看简单的使用过程:
1、指定配置外链:
原有的配置
<add key="RedisServers" value="127.0.0.1:6379,127.0.0.1:6380 - pwd123456"/>
<add key="RedisServersBak" value="127.0.0.1:6381 - pwd123456"/>
将配置写在原的config中,1是不适合大量的实例,要写很长;2是当修改时,会引发(Window下)程序重启(关键是NetCore下还不重启)。
改进后配置(文件后缀可以指定*.ini,*.txt):
<add key="RedisServers" value="redis.ini"/>
<add key="RedisServersBak" value="redisbak.txt"/>
对应的redis.init 文件(一行一个实例):
127.0.0.1:
127.0.0.1: - pwd123456
127.0.0.1: - pwd123456
127.0.0.1: - pwd123456
127.0.0.1: - pwd123456
...
可以无限加
将配置外置后,程序会自动监控文件的变化,每次修改都会即时生效,内部自动调整算法,真正实现高可用。
接下来,你就可以无限的找服务器,启动N多个实例,想加就加,想减就减。
一个高可用的分布式缓存就是这么简单了,当然了,以后要复杂,那就慢慢学习了。
2、关于一致性Hash及主备的说明:
在框架内部的算法中,如果节点失败,会检测有没有设置备用节点:
如果没有,会直接失败。
如果有,会从备用实例中获取来维持服务,如果备用也实例也失败,而本次请求失败(下一次请求会更换备用节点)。
这样可以避免在高并发的情况下产生滚雪球的情景,由一个点失败最终导致把所有的服务器都压倒。
PS:在CYQ.Data 中,Redis 和 MemCache 的底层实现是一样的,所以使用方式都是一样的。
2、Redis、MemCache 分布式下的性能测试。
对于原有的代码改进重构,大约变化了50%左右的代码。
本次在性能上的优化:除了底层Socket小调整,就是命令的合并操作,以及队列池的优化,以及多线程下的稳定保障。
其实,Web are 只是个客户端,要说高性能,其实都是比较出来,只要比别人的快一些,好像就真的高性能了。
所以,测试都需要有个比较的对象。
目前测试的是本机,Win7,Redis 老版本 2.4.6。
1、先自己和自己比:新改动的版本和旧版本比较:
旧版本的测试数据:
新版本的测试数据:
跑在Linux下时(1核2G内存的CentOS7,Redis 版本 3.2.12):
经过整体的代码改动,性能还是整体提升不少的,还支持了高可用的扩展。
只是离官方传说的10w/s,还差了几倍,我猜如果把5个命令打包一起发送,应该就差不多了。
2、看看其它客户端的:
一开始我是没做比较测试,只是刚好在网上看到另一个客户端,写着就是高性能Redis客户端。
看到上面的测试数据,我有点惊讶,这有6w的数据是怎么飘出来的:
SET_JSON using threads run [use time .76s ,370.26/sec]
SET_JSON using threads run [use time .87s ,407.17/sec]
SET_JSON using threads run [use time .65s ,517.8/sec]
但上面没写明是在window还是linux也没写版本,
于是,我就下载了它的客户端(它自带Test运行程序),
然后连上我的redis,运行了一下:
实际上它的数据是这样的:
这是我打开的姿势不对么,还是对环境有特定的要求?
3、和Redis自带的redis-benchmark.exe工具进行比较。
想找找 Redis 在Window平台测试相关的文章,发现都是Redis原生的测试工具的介绍,于是,也用它测试了一下:
发现原生的果然强悍,最高的时候可以飘到6w,看来用C就是不一样。
搞的我都怀疑,你们都是在用并发测试,而我只是用多线程。
4、用了传说中性能好到要收费的:StackExchange.Redis
感觉也差不多啊,收费我还是支持的。
关键是这货相同的NetCore代码,放Linux CentOS7 跑不动:
竟然连不上了,直接返回错误了:
{"success":false,"msg":"It was not possible to connect to the redis server(s). InternalFailure (None, last-recv: 803) on 127.0.0.1:6379/Interactive, Idle, last: GET, origin: ReadFromPipe, outstanding: 2, last-read: 0s ago, last-write: 0s ago, unanswered-write: 0s ago, keep-alive: 60s, state: ConnectedEstablished, mgr: 9 of 10 available, in: 0, last-heartbeat: never, global: 0s ago, v: 2.0.571.20511"}
总结:
CYQ.Data 经过重构升级后,整体提升了不少。
这里要了解一下:CYQ.Data 集成的分布式缓存操作,和其它单独的客户端是不一样的。
因为其它客户端是把所有的Redis命令都实现了,你可以其它客户端操作完整的Redis。
而 CYQ.Data 只是:
Get、Set、DEL、Contains、Clear。
统一了所有类型并保持最简单的缓存操作接口。
最后,献上测试代码:
AppConfig.Cache.RedisServers = "127.0.0.1:6379";//,127.0.0.1:6380 - c123456,127.0.0.1:6381 - c123456,127.0.0.1:6382 - c123456,127.0.0.1:6383 - c123456";
//AppConfig.Cache.RedisServers = "redis.txt";
//AppConfig.Cache.RedisServersBak = "redis.bak.txt"; int readCount = , userDBCount = ;
ThreadPool.SetMaxThreads(, ); new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start(); new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
new ThreadRun(, readCount, userDBCount).Start();
CacheManage.RedisInstance.Clear();//操作对象
Console.WriteLine("End");
Console.WriteLine(CacheManage.RedisInstance.WorkInfo);
Console.WriteLine(CacheManage.RedisInstance.CacheInfo.ToJson(false, false));
----------------------------------------------------------
public class ThreadRun
{
int threadCount, setOrReadCount, useDBCount;
CacheManage cache;
public ThreadRun(int threadCount, int setOrReadCount, int useDBCount)
{
cache = CacheManage.RedisInstance;//操作对象
cache.Clear();
this.threadCount = threadCount;
this.setOrReadCount = setOrReadCount;
this.useDBCount = useDBCount;
}
System.Diagnostics.Stopwatch gloWatch = new System.Diagnostics.Stopwatch();
int runEndCount = ;
bool isEnd = false;
public void Start()
{
AppConfig.Cache.RedisUseDBCount = useDBCount; gloWatch.Start();
for (int i = ; i < threadCount; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadStart), setOrReadCount / threadCount);
} while (!isEnd)
{
Thread.Sleep();
} } public void ThreadStart(object readCount)
{
string rndKey = Guid.NewGuid().ToString().Substring(, );
int max = (int)readCount;
for (int i = ; i < max; i++)
{
string key = rndKey + "key" + i;
if(cache.Set(key, Guid.NewGuid().ToString()))
{ }
else
{
Console.WriteLine("Set 失败 key :" + key);
} } Interlocked.Increment(ref runEndCount);
if (runEndCount >= threadCount && !isEnd)
{
isEnd = true;
//gloWatch.Stop();
//Ng 2000ms
//x 1000ms
long t = gloWatch.ElapsedMilliseconds;
Console.WriteLine(string.Format("ThreadCount : {0} , Run : {1} Time {2} ms ,{3} requests per second. ", threadCount, setOrReadCount, t.ToString(), setOrReadCount * / t)); }
}
}
CYQ.Data 对于分布式缓存Redis、MemCache高可用的改进及性能测试的更多相关文章
- CYQ.Data V5 分布式缓存Redis应用开发及实现算法原理介绍
前言: 自从CYQ.Data框架出了数据库读写分离.分布式缓存MemCache.自动缓存等大功能之后,就进入了频繁的细节打磨优化阶段. 从以下的更新列表就可以看出来了,3个月更新了100条次功能: 3 ...
- CYQ.Data V5 分布式缓存MemCached应用开发介绍
前言 今天大伙还在热议关于.NET Core的东西,我只想说一句:在.NET 跨平台叫了这么多年间,其实人们期待的是一个知名的跨平台案例,而不是一堆能跨平台的消息. 好,回头说说框架: 在框架完成数据 ...
- CYQ.Data 支持分布式数据库(主从备)高可用及负载调试
前言: 继上一篇,介绍 CYQ.Data 在分布式缓存上支持高可用,详见:CYQ.Data 对于分布式缓存Redis.MemCache高可用的改进及性能测试 本篇介绍 CYQ.Data 在对数据库层面 ...
- 分布式缓存Redis应用场景解析
Redis的应用场景非常广泛.虽然Redis是一个key-value的内存数据库,但在实际场景中,Redis经常被作为缓存来使用,如面对数据高并发的读写.海量数据的读写等. 举个例子,A网站首页一天有 ...
- CYQ.Data V5 分布式自动化缓存设计介绍(二)
前言: 最近一段时间,开始了<IT连>创业,所以精力和写的文章多数是在分享创业的过程. 而关于本人三大框架CYQ.Data.Aries.Taurus.MVC的相关文章,基本都很少写了. 但 ...
- 企业项目开发--分布式缓存Redis
第九章 企业项目开发--分布式缓存Redis(1) 注意:本章代码将会建立在上一章的代码基础上,上一章链接<第八章 企业项目开发--分布式缓存memcached> 1.为什么用Redis ...
- 本地缓存google.guava及分布式缓存redis 随笔
近期项目用到了缓存,我选用的是主流的google.guava作本地缓存,redis作分布式 缓存,先说说我对本地缓存和分布式缓存的理解吧,可能不太成熟的地方,大家指出,一起 学习.本地缓存的特点是速度 ...
- 【开源项目系列】如何基于 Spring Cache 实现多级缓存(同时整合本地缓存 Ehcache 和分布式缓存 Redis)
一.缓存 当系统的并发量上来了,如果我们频繁地去访问数据库,那么会使数据库的压力不断增大,在高峰时甚至可以出现数据库崩溃的现象.所以一般我们会使用缓存来解决这个数据库并发访问问题,用户访问进来,会先从 ...
- 分布式缓存——Redis
一.Redis介绍 Redis是一个开源的使用C语言编写.开源.支持网络.可基于内存亦可持久化的日志型.高性能的key-value数据库,并提供多种语言的API.它通常被称为数据结构服务器,因为值(v ...
随机推荐
- Oracle-02:SQL语言的分类或者说SQL语言的组成
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 小结一版: 01.DDL(Data Definition Language)数据定义语言. 用来创建数据库中 ...
- windows10系统终极净化方法
去年购入一台华硕FL8000U,性能很是不错,但是硬件只能兼容win10,不支持win7(linux倒是可以,但是始终用不顺手),win10里面杂七杂八的确实很多,本人重度强迫症+洁癖+极简主义,所以 ...
- TensorFlow 常用函数汇总
本文介绍了tensorflow的常用函数,源自网上整理. TensorFlow 将图形定义转换成分布式执行的操作, 以充分利用可用的计算资源(如 CPU 或 GPU.一般你不需要显式指定使用 CPU ...
- JS中的常量
javascript中没有常量,可以通过创建只能取值不能赋值的私有变量来模仿常量. 创建取值器: var Class = function(){ var NUM = 5; // 在运行时NUM值 ...
- ubuntu旧版本源失效的处理方法
(1)先备份 cp /etc/apt/sources.list /etc/apt/sources.list_backup (2)更换源 在ubuntu的网站中,提供了一个源供那些不再提供支持的版本使用 ...
- nodejs-5.1 ejs模板引擎
ejs官方文档:https://ejs.bootcss.com/ 1.什么是 EJS? "E" 代表 "effective",即[高效]. EJS 是一套简单的 ...
- 我的微服务观,surging 2.0将会带来多大的改变
Surging 自2017年6月16日开源以来,已收到不少公司的关注或者使用,其中既有以海克斯康超大型等外企的关注,也不乏深圳泓达康.重庆金翅膀等传统行业的正式使用,自2019年年初,surging2 ...
- 干货,一文带你超详细了解Session的原理及应用
session 简介 session 是我们 jsp 九大隐含对象的一个对象. session 称作域对象,他的作用是保存一些信息,而 session 这个域对象是一次会话期间使用同一个对象.所以这个 ...
- asp.net core 系列之用户认证(authentication)
ASP.NET Core 的 identity 是一种需要用户登录的会员系统,用户可以创建一个登录信息存储在 Identity 的的账号, 或者也可以使用第三方登录,支持的第三方登录包括:Facebo ...
- 利用Sqoop将MySQL海量测试数据导入HDFS和HBase
声明:作者原创,转载注明出处. 作者:帅气陈吃苹果 一.安装Sqoop 1.下载sqoop,解压.文件夹重命名 wget http://mirror.bit.edu.cn/apache/sqoop/1 ...