点击上方 Java后端,选择 设为星标
优质文章,及时送达
热场准备
当然这里也附上Redis的下载地址:
windows:
https://github.com/MicrosoftArchive/redis/releases
Linux:
https://redis.io/download
开始
Redis封装架构讲解
所以我们Redis的封装有两层,一层是NewLife.Core里面的Redis以及RedisClient。另一层就是NewLife.Redis。这里面的FullRedis是对Redis的实现了Redis的所有的高级功能。这里你也可以认为NewLife.Redis是Redis的一个扩展。
Test实例讲解Redis的基本使用
实例
这里XTrace.UseConsole();是向控制台输出日志,方便调试使用查看结果。
接下来看第一个例子Test1。具体的我都在代码中进行了注释,大家可以看下
static void Test1()
{
var ic = Redis.Create("127.0.0.1:6379", 3);//创建Redis实例,得到FullRedis对象
//var ic = new FullRedis();//另一种实例化的方式
//ic.Server = "127.0.0.1:6379";
//ic.Db = 3;//Redis中数据库
ic.Log = XTrace.Log;//显示日志,进行Redis操作把日志输出,生产环境不用输出日志
// 简单操作
Console.WriteLine("共有缓存对象 {0} 个", ic.Count);//缓存对象数量
ic.Set("name", "大石头");//Set K-V结构,Set第二个参数可以是任何类型
Console.WriteLine(ic.Get<String>("name"));//Get泛型,指定获取的类型
ic.Set("time", DateTime.Now, 1);//过期时间秒
Console.WriteLine(ic.Get<DateTime>("time").ToFullString());
Thread.Sleep(1100);
Console.WriteLine(ic.Get<DateTime>("time").ToFullString());
// 列表
var list = ic.GetList<DateTime>("list");
list.Add(DateTime.Now);
list.Add(DateTime.Now.Date);
list.RemoveAt(1);
Console.WriteLine(list[list.Count - 1].ToFullString());
// 字典
var dic = ic.GetDictionary<DateTime>("dic");
dic.Add("xxx", DateTime.Now);
Console.WriteLine(dic["xxx"].ToFullString());
// 队列
var mq = ic.GetQueue<String>("queue");
mq.Add(new[] { "abc", "g", "e", "m" });
var arr = mq.Take(3);
Console.WriteLine(arr.Join(","));
// 集合
var set = ic.GetSet<String>("181110_1234");
set.Add("xx1");
set.Add("xx2");
set.Add("xx3");
Console.WriteLine(set.Count);
Console.WriteLine(set.Contains("xx2"));
Console.WriteLine("共有缓存对象 {0} 个", ic.Count);
}
-
数据库中不合法的时间处理:判断时间中的年份,是否大于2000年。如果小于2000就认为不合法。习惯大于小于号不习惯用等于号,这样可以处理很多意外的数据
-
Set的时候最好指定过期时间防止有些需要删除的数据,我们忘记删了
-
Redis异步尽量不用,因为Redis延迟本身很小,大概在100us-200us,再一个就是Redis本身是单线程的,异步任务切换的耗时比网络耗时还要大。List用法:物联网中数据上传,量比较大时,我们可以把这些数据先放在Redis的List中,比如说一秒钟1万条,然后再批量取出来然后批量插入数据库中。这时候要设置好key,可以前缀+时间,对于已经处理的List可以进行remove移除。
压力测试
static void Main(String[] args)
{
XTrace.UseConsole();
// 激活FullRedis,否则Redis.Create会得到默认的Redis对象
FullRedis.Register();
Test4();
Console.ReadKey();
}
static void Test4()
{
var ic = Redis.Create("127.0.0.1:6379", 5);
//var ic = new MemoryCache();
ic.Bench();
}
运行的结果如下图所示:
测试就是进行get,set remove,累加等的操作。大家可以看到在我本机上轻轻松松的到了六十万,多线程的时候甚至到了一百多万。为什么会达到这么高的ops呢,下面给大家说一下。
-
Bench 会分根据线程数分多组进行添删改压力测试。
-
rand 参数,是否随机产生key/value。
-
batch 批大小,分批执行读写操作,借助GetAll/SetAll进行优化。
Redis中NB的函数来提升性能
setall与getall性能很恐怖,官方公布的ops也就10万左右,为什么我们的测试轻轻松松到五十万甚至上百万,因为我们就用了setall,getall。
如果get,set两次以上,建议用getall,setall
-
Add:Redis中没有这个Key就添加,有了就不要添加,返回false
-
Replace:有则替换,还会返回原来的值,没有则不进行操作
Add跟Replace就是实现Redis分布式锁的关键
Redis使用技巧,经验分享
特性
-
在ZTO大数据实时计算广泛应用,200多个Redis实例稳定工作一年多,每天处理近1亿包裹数据,日均调用量80亿次
-
低延迟,Get/Set操作平均耗时200~600us(含往返网络通信)
-
大吞吐,自带连接池,最大支持1000并发
-
高性能,支持二进制序列化(默认用的json,json很低效,转成二进制性能会提升很多)
Redis经验分享
-
在Linux上多实例部署,实例个数等于处理器个数,各实例最大内存直接为本机物理内存,避免单个实例内存撑爆(比方说8核心处理器,那么就部署8个实例)
-
把海量数据(10亿+)根据key哈希(Crc16/Crc32)存放在多个实例上,读写性能成倍增长
-
采用二进制序列化,而非常见的Json序列化
-
合理设计每一对Key的Value大小,包括但不限于使用批量获取,原则是让每次网络包控制在1.4k字节附近,减少通信次数(实际经验几十k,几百k也是没问题的)
-
Redis客户端的Get/Set操作平均耗时200~600us(含往返网络通信),以此为参考评估网络环境和Redis客户端组件(达不到就看一下网络,序列化方式等等)
-
使用管道Pipeline合并一批命令
-
Redis的主要性能瓶颈是序列化、网络带宽和内存大小,滥用时处理器也会达到瓶颈
-
其它可查优化技巧
以上经验,源自于300多个实例4T以上空间一年多稳定工作的经验,并按照重要程度排了先后顺序,可根据场景需要酌情采用!
缓存Redis的兄弟姐妹
Redis实现ICache接口,它的孪生兄弟MemoryCache,内存缓存,千万级吞吐率。
各应用强烈建议使用ICache接口编码设计,小数据时使用MemoryCache实现;
数据增大(10万)以后,改用Redis实现,不需要修改业务代码。
提问环节聊聊大数据中Redis使用的经验,问题
如果对性能要求不是很高直接用json序列化实体就好,没必要使用字典进行存储。
队列其实就是用List实现的,也是基于List封装的。左进右出的话直接队列就好。Redis的List结构比较有意思,既可以左进右出,也能右进左出。所以它既可以实现列表结构,也能队列,也能实现栈
大部分场景都不会有偏差,可能对于大公司数据量比较大的场景会有些偏差
略。自己看视频吧!o(∩_∩)o 哈哈!(因为我没听清!)
分表分库,拆分到一千万以内。
视频地址
视频已经上传至百度云,大家可以自行下载观看
链接:https://pan.baidu.com/s/1sOW_PLjxQE8C2msbDfizeA
提取码:c7dp
观看指南(笑笑提供)
总结
依乐祝
www.cnblogs.com/yilezhu/p/9941208.html
。同时
标星(置顶)
本公众号可以第一时间接受到博文推送。
《Java技术栈学习手册》
,覆盖了Java技术、面试题精选、Spring全家桶、Nginx、SSM、微服务、数据库、数据结构、架构等等。
获取方式:点“ 在看,关注公众号 Java后端 并回复 777 领取,更多内容陆续奉上。
喜欢文章,点个在看
本文分享自微信公众号 - Java后端(web_resource)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。