Redis 基本使用及百亿数据量中的使用技巧
mhr18 2024-11-14 16:16 24 浏览 0 评论
优质文章,及时送达
热场准备
熟悉的开场白,大家晚上好啊,今天给大家分享的是Redis在大数据中的使用,可能真正讲的是一些redis的使用技巧,Redis基本的一些东西。
首先给大家个地址,源码以及实例都在里面,当然今天的分享也是按照里面的实例来进行的,大家可以先进行下载。
http://git.newlifex.com/NewLife/NewLife.Redis
windows:
https://github.com/MicrosoftArchive/redis/releases
http://x.newlifex.com/Redis-x64-3.2.100.msi
Linux:
https://redis.io/download
开始
Redis封装架构讲解
实际上NewLife.Redis是一个完整的Redis协议的功能的实现,但是redis的核心功能并没有在这里面,Redis的核心功能的实现是在NewLife.Core里面。这里可以打开看一下,NewLife.Core里面有一个NewLife.Caching的命名空间,里面有一个Redis类里面实现了Redis的基本功能,另一个类是RedisClient是Redis的客户端。Redis的核心功能就是有这两个类实现。RedisClient代表着Redis客户端对服务器的一个连接。
对了,我把优质 Redis 文章整理成 PDF ,关注微信公众号 Java后端 ,回复 666 即可下载。
Redis真正使用的时候有一个Redis连接池,里面存放着很多个RedisClient对象。
所以我们Redis的封装有两层,一层是NewLife.Core里面的Redis以及RedisClient。另一层就是NewLife.Redis。这里面的FullRedis是对Redis的实现了Redis的所有的高级功能。这里你也可以认为NewLife.Redis是Redis的一个扩展。
Test实例讲解Redis的基本使用
实例
打开Program.cs看下代码
这里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);
}
1、Set的时候如果是字符串或者字符数据的话Redis会直接保存起来(字符串内部机制也是保存二进制),如果是其他类型会默认进行json序列化然后再保存起来
2、Get的时候如果是字符串或者字符数据会直接获取,如果是其他类型会进行json反序列化
3、Set第三个参数过期时间单位是秒。
4、vs调试小技巧,按F5或者直接工具栏“启动”会编译整个解决方案会很慢(VS默认),可以选中项目然后右键菜单选择调试->启动新实例。会只编译将会用到的项目,这样对调试来说会快很多。
5、大家运行调试后可以看到控制台输出的内容:向右的箭头=》是ic.Log=XTrace.Log输出的日志
6、字典的使用:对象的话需要把json全部取出来然后转换成对象,而字典的话就可以直接取某个字段。
7、队列是List结构实现的,使用场景可以上游数据太多,下游处理不过来的时候,那么就可以使用这个队列。上游的数据发到队列,然后下游慢慢的消费。另一个应用,跨语言的协同工作,比方说其他语言实现的程序往队列里面塞数据,然后另一种语言来进行消费处理。哈,这种方式类似mq的概念,虽然有点low,但是也很好用。
8、集合,用的比较多的是用在一个需要精确判断的去重功能。像我们每天有三千万订单,这三千万订单可以有重复,这时候我想统计下一共有订单,这时候直接数据库group by是不大可能的,因为数据库中分了十几张表,这里分享个实战经验:比方说揽收,商家发货了,网点要把件收回来,但是收回来之前网点不知道自己有多少货啊,这时候我们做了一个功能,也就是订单会发送到我们公司来,我们会建一个time_site的key的集合,而且集合本身有去重的功能,而且我们可以很方便的通过set.Count功能来统计数量,当件被揽收以后,我们后台把这个件从集合中Remove掉.然后这个Set中存在的就是网点还没有揽收的件,这时候通过Count就会知道这个网点今天还有多少件没有揽收。实际使用中这个数量比较大,因为有几万个网点。
9、Redis中布隆过滤器,去重的,面试的时候问的比较多
10、小经验分享:
数据库中不合法的时间处理:判断时间中的年份,是否大于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的函数来提升性能
上面的操作如果大家都掌握的基本算Redis入门了,接下来进行进阶。会了基本比别人更胜一筹了。
1、GetAll与SetAll
GetAll:比方说我要取十个key,这个时候可以用getall。这时候redis就执行了一次命令。比方说我要取10个key那么用get的话要取10次,如果用getall的话要用1次。一次getall时间大概是get的一点几倍,但是10次get的话就是10倍的时间,这个账你应该会算吧。强烈推荐大家用getall。
setall 跟getall相似。批量设置K-V.
setall与getall性能很恐怖,官方公布的ops也就10万左右,为什么我们的测试轻轻松松到五十万甚至上百万,因为我们就用了setall,getall。
如果get,set两次以上,建议用getall,setall
2、Redis管道Pipeline
比如执行10次命令会打包成一个包集体发过去执行,这里实现的方式是StartPipeline开始,StopPipeline结束中间的代码就会以管道的形式执行。这里推荐使用我们的更强的武器,AutoPipeline自动管道属性。管道操作到一定数量时,自动提交,默认0。使用了AutoPipeline,就不需要StartPipeline,StopPipeline指定管道的开始结束了!
3、Add与Replace
Add:Redis中没有这个Key就添加,有了就不要添加,返回false
Replace:有则替换,还会返回原来的值,没有则不进行操作
Add跟Replace就是实现Redis分布式锁的关键
Redis使用技巧,经验分享
在项目的Readme中,这里摘录下:
特性
在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使用的经验,问题
1、一条数据多个key怎么设置比较合理?
如果对性能要求不是很高直接用json序列化实体就好,没必要使用字典进行存储。
2、队列跟List有什么区别?左进右出的话用List还是用队列比较好?
队列其实就是用List实现的,也是基于List封装的。左进右出的话直接队列就好。Redis的List结构比较有意思,既可以左进右出,也能右进左出。所以它既可以实现列表结构,也能队列,也能实现栈
3、存放多个字段的类性能一样吗?
大部分场景都不会有偏差,可能对于大公司数据量比较大的场景会有些偏差
4、可否介绍一下使用Redis进行数据计算、统计的场景?
略。自己看视频吧!o(∩_∩)o 哈哈!(因为我没听清!)
5、大数据写入到数据库之后 比如数据到亿以上的时候 统计分析这块 查询这块 能不能分享些经验。
分表分库,拆分到一千万以内。
6、CPU为何暴涨?
程序员终极理念:CPU达到百分百,然后性能达到最优,尽量不要浪费。最痛恨的是:如果cpu不到百分百,性能没法提升了,说明代码有问题!
视频地址
视频已经上传至百度云,大家可以自行下载观看
链接:https://pan.baidu.com/s/1sOW_PLjxQE8C2msbDfizeA
提取码:c7dp
观看指南(笑笑提供)
总结
虽然Redis会用,但是没有像大石头这样的大数据使用场景。今天的视频收获颇丰,可能大部分人跟我一样,没有大石头的使用场景,但是值得借鉴的经验还是很丰富的!期待下一次的精彩分享。
作者:依乐祝
www.cnblogs.com/yilezhu/p/9941208.html
-END-
如果看到这里,说明你喜欢这篇文章,请 转发、点赞。同时 标星(置顶)本公众号可以第一时间接受到博文推送。
1. 多模块SSM项目骨架Spring Boot 整合 Netty(附源码)3.Nginx 从入门到实践,万字详解!我用一根网线攻击了舍友!
最近整理一份面试资料《Java技术栈学习手册》,覆盖了Java技术、面试题精选、Spring全家桶、Nginx、SSM、微服务、数据库、数据结构、架构等等。
相关推荐
- 说说Redis的单线程架构(redis的单线程模型)
-
一句话总结Redis采用单线程处理命令请求,避免了多线程的上下文切换和锁竞争,保证原子性操作。其基于内存的高效执行和I/O多路复用模型支撑了高并发性能。网络I/O和持久化操作(如RDB/AOF)由后台...
- 答记者问之 - Redis 的高效架构与应用模式解析
-
问:极客程序员你好,请帮我讲一讲redis答:redis主要涉及以下核心,我来一一揭幕Redis的高效架构与应用模式解析Redis是一个开源的内存数据存储系统,因其高性能、丰富的数据结构和易用性...
- Redis的5种核心数据结构,及其最经典的“应用场景”
-
Redis凭什么稳坐缓存界头把交椅?全靠这五个“身怀绝技”的数据结构!在分布式系统的江湖里,Redis就像一位身怀绝技的武林高手,而它的五大核心数据结构正是克敌制胜的五套绝学。今天咱们就来拆解这些独门...
- 精准定位文件包含漏洞:代码审计中的实战思维
-
前言最近看到由有分析梦想cms的,然后也去搭建了一个环境看了一看,发现了一个文件包含漏洞的点,很有意思,下面是详细的复现和分析,以后代码审计又多了一中挖掘文件包含漏洞的新思路环境搭建下载https...
- ARDM:一款国产跨平台的Redis管理工具
-
ARDM(AnotherRedisDesktopManager)是一款免费开源的Redis桌面管理客户端,支持Windows、Mac、Linux跨平台。功能特性ARDM提供的主要功能如...
- SpringBoot的Web应用开发——Web缓存利器Redis的应用!
-
Web缓存利器Redis的应用Redis是目前使用非常广泛的开源的内存数据库,是一个高性能的keyvalue数据库,它支持多种数据结构,常用做缓存、消息代理和配置中心。本节将简单介绍Redis的使...
- Windows服务器部署CRMEB开源电商系统,详细教程来了!
-
安装PHP已经安装过PHP的可以跳过首先安装VC运行库下载地址https://docs.microsoft.com/zh-cn/cpp/windows/latest-supported-vc-redi...
- Windows系统下Redis各个安装包介绍与选择指南
-
简介Redis作为高性能的键值数据库,广泛应用于缓存、消息队列等场景。在Windows系统中部署Redis时,用户可以选择多种安装包以满足不同的需求。本文将详细介绍以下Redis8.0.3版本的安装...
- 从面试题入手,深度剖析Redis Cluster原理
-
揭开RedisCluster的神秘面纱**在当今数字化浪潮中,数据量呈爆炸式增长,应用程序对数据存储和处理的要求也日益严苛。Redis作为一款高性能的内存数据库,凭借其出色的读写速度和丰富的数...
- 给大家推荐些好的c语言代码的网站
-
C语言,那就来推荐几个吧,部分含有C++:1、TheLinuxKernelArchives(kernel.org)Linux内核源码,仅限于C,但内核庞大,不太适合新手;2、redis(redi...
- Redis String 类型的底层实现与性能优化
-
RedisString是Redis中最基础也是应用最广泛的数据类型,它能存储文本、数字、二进制数据等多种形式的信息。深入理解其底层实现对构建高性能分布式系统至关重要。Redis字符串的底层结...
- 阿里面试问:Redis 为什么把简单的字符串设计成 SDS?
-
分享了一道面阿里的redis题,我看了以后觉得挺有意思。题目大致是这样的面试官:了解redis的String数据结构底层实现嘛?铁子:当然知道,是基于SDS实现的面试官:redis是用C语言开发的,那...
- 编程语言那么多,为何C语言能成为最成功的语言?
-
编程语言那么多,为何C语言能成为最成功的语言?2025年嵌入式岗位暴增47%,新人却还在问"C语言过时了吗"。真相是连机器人关节驱动都得靠它写,不会指针连芯片手册都看不懂。见过用Pyt...
- go-zero 使用 redis 作为 cache 的 2 种姿势
-
在go-zero框架内,如在rpc的应用service中,其内部已经预置了redis的应用,所以我们只需要在配置中加入相关字段即可,另外,在svcContext声明redisc...
- Redis事务深度解析:ACID特性、执行机制与生产实践指南
-
一、Redis事务的本质与核心机制Redis事务通过MULTI、EXEC、WATCH等命令实现,其本质是将多个命令序列化后一次性执行,而非传统数据库的严格事务模型。核心特点如下:命令队列化:MULT...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle主从同步 (56)
- oracle 乐观锁 (53)
- redis 命令 (83)
- php redis (97)
- redis 存储 (67)
- redis 锁 (74)
- 启动 redis (73)
- redis 时间 (60)
- redis 删除 (69)
- redis内存 (64)
- redis并发 (53)
- redis 主从 (71)
- redis同步 (53)
- redis 哨兵 (52)
- redis结构 (53)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)