一、Redis封装架构讲解实际上NewLife.Redis是一个完整的Re...
今天将会跟大家讨论一些Redis在大数据中的使用,包括一些Redis的使用技巧和其他的一些内容。
一、Redis封装架构讲解
实际上NewLife.Redis是一个完整的Redis协议功能的实现,但是Redis的核心功能并没有在这里面,而是在NewLife.Core里面。
这里可以打开看一下,NewLife.Core里面有一个NewLife.Caching的命名空间,里面有一个Redis类,里面实现了Redis的基本功能;另一个类是RedisClient是Redis的客户端。
Redis的核心功能就是有这两个类实现,RedisClient代表着Redis客户端对服务器的一个连接。Redis真正使用的时候有一个Redis连接池,里面存放着很多个RedisClient对象。
所以我们Redis的封装有两层,一层是NewLife.Core里面的Redis以及RedisClient;另一层就是NewLife.Redis。这里面的FullRedis是对Redis的实现了Redis的所有的高级功能。
这里你也可以认为NewLife.Redis是Redis的一个扩展。
二、Test实例讲解Redis的基本使用
1、实例
打开Program.cs看下代码:
这里XTrace.UseConsole();是向控制台输出日志,方便调试使用查看结果。
接下来看第一个例子Test1,具体的我都在代码中进行了注释,大家可以看下:
Set的时候,如果是字符串或者字符数据的话,Redis会直接保存起来(字符串内部机制也是保存二进制),如果是其他类型,会默认进行json序列化然后再保存起来。
Get的时候,如果是字符串或者字符数据会直接获取,如果是其他类型会进行json反序列化。
Set第三个参数过期时间单位是秒。
vs调试小技巧,按F5或者直接工具栏“启动”会编译整个解决方案会很慢(VS默认),可以选中项目然后右键菜单选择调试->启动新实例,会只编译将会用到的项目,这样对调试来说会快很多。
大家运行调试后可以看到控制台输出的内容:向右的箭头=》是ic.Log=XTrace.Log输出的日志。
字典的使用:对象的话,需要把json全部取出来,然后转换成对象,而字典的话,就可以直接取某个字段。
队列是List结构实现的,上游数据太多,下游处理不过来的时候,就可以使用这个队列。上游的数据发到队列,然后下游慢慢的消费。另一个应用,跨语言的协同工作,比方说其他语言实现的程序往队列里面塞数据,然后另一种语言来进行消费处理。这种方式类似MQ的概念,虽然有点low,但是也很好用。
集合,用的比较多的是用在一个需要精确判断的去重功能。像我们每天有三千万订单,这三千万订单可以有重复。这时候我想统计下一共有订单,这时候直接数据库group by是不大可能的,因为数据库中分了十几张表,这里分享个实战经验:
比方说揽收,商家发货了,网点要把件收回来,但是收回来之前网点不知道自己有多少货,这时候我们做了一个功能,也就是订单会发送到我们公司来。我们会建一个time_site的key的集合,而且集合本身有去重的功能,而且我们可以很方便的通过set.Count功能来统计数量,当件被揽收以后,我们后台把这个件从集合中Remove掉。然后这个Set中存在的就是网点还没有揽收的件,这时候通过Count就会知道这个网点今天还有多少件没有揽收。实际使用中这个数量比较大,因为有几万个网点。
Redis中布隆过滤器,去重的,面试的时候问的比较多。
小经验分享:
数据库中不合法的时间处理:判断时间中的年份是否大于2000年,如果小于2000就认为不合法;习惯大于小于号不习惯用等于号,这样可以处理很多意外的数据;
Set的时候最好指定过期时间,防止有些需要删除的数据我们忘记删了;
Redis异步尽量不用,因为Redis延迟本身很小,大概在100us-200us,再一个就是Redis本身是单线程的,异步任务切换的耗时比网络耗时还要大;
List用法:物联网中数据上传,量比较大时,我们可以把这些数据先放在Redis的List中,比如说一秒钟1万条,然后再批量取出来然后批量插入数据库中。这时候要设置好key,可以前缀+时间,对已处理的List可以进行remove移除。
2、压力测试
接下来看第四个例子,我们直接做压力测试,代码如下:
运行的结果如下图所示:
测试就是进行get,set remove,累加等的操作。大家可以看到在我本机上轻轻松松的到了六十万,多线程的时候甚至到了一百多万。
为什么会达到这么高的Ops呢?下面给大家说一下:
Bench会分根据线程数分多组进行添删改压力测试;
rand参数,是否随机产生key/value;
batch批大小,分批执行读写操作,借助GetAll/SetAll进行优化。
3、Redis中NB的函数来提升性能
上面的操作如果大家都掌握了就基本算Redis入门了,接下来进行进阶。如果能全然吃透,差不多就会比别人更胜一筹了。
GetAll()与SetAll()
GetAll:比方说我要取十个key,这个时候可以用getall。这时候Redis就执行了一次命令。比方说我要取10个key那么用get的话要取10次,如果用getall的话要用1次。1次getall时间大概是get的一点几倍,但是10次get的话就是10倍的时间,这个账你应该会算吧?强烈推荐大家用getall。
setall跟getall相似,批量设置K-V。
setall与getall性能很恐怖,官方公布的Ops也就10万左右,为什么我们的测试轻轻松松到五十万甚至上百万?因为我们就用了setall,getall。如果get,set两次以上,建议用getall,setall。
Redis管道Pipeline
比如执行10次命令会打包成一个包集体发过去执行,这里实现的方式是StartPipeline()开始,StopPipeline()结束中间的代码就会以管道的形式执行。
这里推荐使用更强的武器,AutoPipeline自动管道属性。管道操作到一定数量时,自动提交,默认0。使用了AutoPipeline,就不需要StartPipeline,StopPipeline指定管道的开始结束了。
Add与Replace
Add:Redis中没有这个Key就添加,有了就不要添加,返回false;
Replace:有则替换,还会返回原来的值,没有则不进行操作。
Add跟Replace就是实现Redis分布式锁的关键。
三、Redis使用技巧,经验分享
在项目的Readme中,这里摘录下:
1、特性
在ZTO大数据实时计算广泛应用,200多个Redis实例稳定工作一年多,每天处理近1亿包裹数据,日均调用量80亿次;
低延迟,Get/Set操作平均耗时200~600us(含往返网络通信);
大吞吐,自带连接池,最大支持1000并发;
高性能,支持二进制序列化(默认用的json,json很低效,转成二进制性能会提升很多)。
2、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以上空间一年多稳定工作的经验,并按照重要程度排了先后顺序,可根据场景需要酌情采用。
3、缓存Redis的兄弟姐妹
Redis实现ICache接口,它的孪生兄弟MemoryCache,内存缓存,千万级吞吐率。各应用强烈建议使用ICache接口编码设计,小数据时使用MemoryCache实现;数据增大(10万)以后,改用Redis实现,不需要修改业务代码。
Java高级部落
共享Java行业资讯,分享公司内部核心干货,中高Java开发级技术,关注我一起探索Java编程架构之路。
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。其中Redis提供了5种数据结构,为了我们...

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。其中Redis提供了5种数据结构,为了我们能够更加清楚这些数据结构的使用场景,接下来我们将对其进行一一对比与分析。

一、字符串
字符串类型是redis最基础的数据结构,首先键是字符串类型,而且其他几种结构都是在字符串类型基础上构建的,所以字符串类型能为其他四种数据结构的学习尊定基础。字符串类型实际上可以是字符串(简单的字符串、复杂的字符串(xml、json)、数字(整数、浮点数)、二进制(图片、音频、视频)),但最大不能超过512M。
使用场景:
缓存功能:字符串最经典的使用场景,redis最为缓存层,Mysql作为储存层,绝大部分请求数据都是redis中获取,由于redis具有支撑高并发特性,所以缓存通常能起到加速读写和降低 后端压力的作用。(redis为何具备支撑高并发的特性,下次文章讲解)。
计数器:许多运用都会使用redis作为计数的基础工具,他可以实现快速计数、查询缓存的功能,同时数据可以一步落地到其他的数据源。如:视频播放数系统就是使用redis作为视频播放数计数的基础组件。
共享session:出于负载均衡的考虑,分布式服务会将用户信息的访问均衡到不同服务器上,用户刷新一次访问可能会需要重新登录,为避免这个问题可以用redis将用户session集中管理,在这种模式下只要保证redis的高可用和扩展性的,每次获取用户更新或查询登录信息都直接从redis中集中获取。
限速:处于安全考虑,每次进行登录时让用户输入手机验证码,为了短信接口不被频繁访问,会限制用户每分钟获取验证码的频率。
二、哈希
在redis中哈希类型是指键本身又是一种键值对结构,如value={{field1,value1},......fieldN,valueN}}
使用场景:哈希结构相对于字符串序列化缓存信息更加直观,并且在更新操作上更加便捷。所以常常用于用户信息等管理,但是哈希类型和关系型数据库有所不同,哈希类型是稀疏的,而关系型数据库是完全结构化的,关系型数据库可以做复杂的关系查询,而redis去模拟关系型复杂查询,开发困难,维护成本高。
三、列表
列表类型是用来储存多个有序的字符串,列表中的每个字符串成为元素(element),一个列表最多可以储存2的32次方-1个元素,在redis中,可以队列表两端插入(pubsh)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下表的元素等,列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发中有很多应用场景。
优点:
列表的元素是有序的,这就意味着可以通过索引下标获取某个或某个范围内的元素列表。
列表内的元素是可以重复的。
使用场景:
消息队列: redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端是用lupsh从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞时的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性clipboard.png消息队列模型↑
文章列表:每个用户都有属于自己的文章列表,现在需要分页展示文章列表,此时可以考虑使用列表,列表不但有序,同时支持按照索引范围获取元素。
四、集合
集合类型也是用来保存多个字符串的元素,但和列表不同的是集合中不允许有重复的元素,并且集合中的元素是无序的,不能通过索引下标获取元素,redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集,并合理的使用好集合类型,能在实际开发中解决很多实际问题。
使用场景:
标签(tag):集合类型比较典型的使用场景,如一个用户对娱乐、体育比较感兴趣,另一个可能对新闻感兴 趣,这些兴趣就是标签,有了这些数据就可以得到同一标签的人,以及用户的共同爱好的标签,这些数据对于用户体验以及曾强用户粘度比较重要。(用户和标签的关系维护应该放在一个事物内执行,防止部分命令失败造成数据不一致)
五、有序集合
有序集合和集合有着必然的联系,他保留了集合不能有重复成员的特性,但不同得是,有序集合中的元素是可以排序的,但是它和列表的使用索引下标作为排序依据不同的是,它给每个元素设置一个分数,作为排序的依据。(有序集合中的元素不可以重复,但是csore可以重复,就和一个班里的同学学号不能重复,但考试成绩可以相同)。
redis中所有数据结构都以唯一的key字符串作为名称,然后通过这个唯一的key来获取对应的value 不同的数据类型数据结构差异就在于value的结构不一样 1. 字符串(string) value的数据结构(数组) 字符串value...
redis中所有数据结构都以唯一的key字符串作为名称,然后通过这个唯一的key来获取对应的value不同的数据类型数据结构差异就在于value的结构不一样

1. 字符串(string)

value的数据结构(数组)
字符串value数据结构类似于数组,采用与分配容易空间来减少内存频繁分配
当字符串长度小于1M时,扩容就是加倍现有空间
如果字符串长度超过1M时,扩容时最多扩容1M空间,字符串最大长度为 512M
字符串的使用场景(缓存)
字符串一个常见的用途是缓存用户信息,我们将用户信息使用JSON序列化成字符串
取用户信息时会经过一次反序列化的过程

2. list(列表)

value的数据结构(双向链表)
列表的数据结构是双向链表,这意味着插入和删除的时间复杂度是0(1),索引的时间复杂度位0(n)
当列表弹出最后一个元素后,该数据结构会被自动删除,内存被回手
列表的使用场景(队列、栈)
3. hash(字典)
value的数据结构(HashMap)
redis中的字典也是HashMap(数组+列表)的二维结构
不同的是redis的字典的值只能是字符串
hash的使用场景(缓存)
hash结构也可以用来缓存用户信息,与字符串一次性全部序列化整个对象不同,hash可以对每个字段进行单独存储
这样可以部分获取用户信息,节约网络流量
hash也有缺点,hash结构的存储消耗要高于单个字符串

4. set(集合)

value的数据结构(字典)
redis中的集合相当于一个特殊的字典,字典的所有value都位null
当集合中的最后一个元素被移除后,数据结构会被自动删除,内存被回收
set使用场景
set结构可以用来存储某个活动中中奖的用户ID,因为有去重功能,可以保证同一用户不会中间两次

5. zset(有序集合)

value的数据结构(跳跃列表)
zset一方面是一个set,保证了内部的唯一性
另一方面它可以给每一个value赋予一个score,代表这个value的权重
zset内部实现用的是一种叫做“跳跃列表”的数据结构
zset最后一个元素被移除后,数据结构就会被自动删除,内存也会被回收
zset应用场景
粉丝列表:value(粉丝ID),score(关注时间),这样可以轻松按关注事件排序
学生成绩:value(学生ID),score(考试成绩),这样可以轻松对成绩排序
四、Redis缓存大数据快速清理工具设计。 五、Redis热点缓存预热 一、Redis缓存功能组件介绍 本文主要记录系统使用Redis缓存的实现思路,解决电商平台常见的一些问题,集成通用的redis组件能力。 功能模块涉及: ...
学习该课程后,可以搭建自己的排行榜系统,用户推荐系统,以及对应的衍生产品,比如淘宝热卖商品,今日头条新闻推荐。... 介绍当前大数据时代下,热门排行榜系统怎么做,用户推荐系统怎么做?分析及建立模型。...
1.如何一步步构建我们的实时处理系统(Flume+Kafka+Storm+Redis)	2.实时处理网站的用户访问日志,并统计出该网站的PV、UV	3.将实时分析出的PV、UV动态地展示在我们的前面页面上 如果你对上面提及的大数据...
如果你对上面提及的大数据组件已经有所认识,或者对如何构建大数据实时处理系统感兴趣,那么就可以尽情阅读下面的内容了。 需要注意的是,核心在于如何构建实时处理系统,而这里给出的案例是实时统计某个网站的PV...
为什么使用Redis pom.xml配置文件 代码片段展示 1.从mysql中查询到Telid和dateid,先保存到map集合中 2.向redis中存储电话号码和电话号码的id(date和dateid一样) 整体代码 表设计介绍 在本项目的MapReduce...
redis是内存中的数据结构存储系统,一个key-value类型的非关系型数据库,可持久化的数据库,相对于关系型数据库(数据主要存在硬盘中),性能高,因此我们一般用redis来做缓存使用;并且redis支持丰富的数据类型,...
在大数据时代,由于网络请求的并发,导致的数据库I/O开销巨大,所以为了缓解数据库的压力,缓存技术必不可少,而这其中redis基本是服务器的缓存服务之一,虽然缓存技术很好用,但是也会出现各种各样的问题,这里就最...
什么是Redis缓存穿透、缓存击穿、缓存雪崩?缓存穿透什么是缓存穿透?如何解决缓存穿透?缓存空值BloomFilter布隆过滤器缓存击穿什么是缓存击穿如何解决缓存击穿异步定时更新互斥锁缓存雪崩什么是缓存雪崩?如何避免...
Redis缓存入门 1.nosql介绍——Redis简介 a.什么是NoSQL	NoSQL(Not Only SQL),不仅仅是SQL,是一项全新的数据库理念,泛指非关系型数据库。 b.为什么需要NoSQL (1)High performance-对数据库高并发读写的需求 ...
Redis缓存穿透与缓存雪崩 缓存穿透 缓存只是为了缓解数据库压力而添加的一层保护层,当从缓存中查询不到我们需要的数据就要去数据库中查询了。如果被黑客利用,频繁去访问缓存中没有的数据,那么缓存就失去了存在...
Asp.Net性能优化之使用Redis缓存(入门) 1:使用Redis缓存的优化思路 redis的使用场景很多,仅说下本人所用的一个场景: 1.1对于大量的数据读取,为了缓解数据库的压力将一些不经常变化的而又读取频繁的数据存入...
文章目录redis缓存数据库缓存数据库介绍NoSQL数据库的四大分类键值(Key-Value)存储数据库列存储数据库。文档型数据库图形(Graph)数据库redis数据库Redis优点异常快速 :支持丰富的数据类型 :操作都是原子的 :...
1、Redis缓存雪崩 一句话就是:大面积的缓存失效,Redis 相当于没有了,直接将查询请求打到数据库,然后数据库顶不住,崩了。 例如:设置缓存更新时间为12:00, 但恰好有秒杀、促销活动,一下涌进很多的请求,...
Redis是C语言开发的一个高性能键值对(key -value) 内存数据库,可以用作数据库,缓存和消息中间件等。 1. 作为内存数据库,它的性能非常优秀,数据存储在内存当中,读写速度非常快,支持并发10W QPS(每秒查询次数...
将数据保存到Redis的过程中,可能会发生各种异常,包括redis集群挂掉、redis连接错误、redis写入错误等。面向失败设计思想的一个重要的最佳实践,就是保证数据幂等性。允许失败的时候进行重试。所以在设计redis key...
Redis缓存原理及设计 缓存基本思想 什么是缓存? 缓存原指CPU上的一种高速存储器,它先于内存与CPU交换数据,速度很快。 现在泛指存储在计算机上的原始数据的复制集,便于快速访问。 在互联网技术中,缓存是...
项目修炼之路(5)高并发下优化Redis缓存效率 ...
Redis缓存穿透、缓存击穿、缓存雪崩的原理和解决办法1.前言2.缓存穿透的解决办法3.缓存击穿解决办法4.缓存雪崩的解决办法 1.前言 在大数据时代,由于网络请求的并发,导致的数据库I/O开销巨大,所以为了缓解数据库的...
高性能、高可用、高可扩展性 … 了解:3V+3高大数据的3V:主要是描述问题的大数据的3高:主要是对程序的要求 NoSQL的四大分类 KV键值对: 新浪:Redis 美团:Redis = Tair 阿里、百度:Redis + memecache 文档型...