redis使用和调优
redis是一个key-value数据库,就像是java中List,Set,Map一样,使用内存存储数据,c语言编写,读写速度都很快。下载程序包,只有2Mb大小,可以说非常轻量级了。打开redis的目录,可以看到一个makefile,这个正是为了c语言编译的。如果有编译好的二进制文件,只要运行就可以了。
学习redis,首先就是使用redis-cli练手,属性其5种数据类型和基本命令。接下来就是怎么通过网络访问redis,基本理念就是开发一个client,能够连接到xxx:6379端口,然后向其发送命令行,获取输出。只不过应用层协议是resp,儿不是我们熟悉的http。查看官方推荐的java-redis-client,这个带注释不到400行的代码就完成了这个功能,真的很强大,值得一读并模仿。但是这对于实际使用远远不够,最基本的问题就是性能问题。
查看官网资料,在document菜单下面,有一个specification,可以看到Redis Protocol specification超链接,说明了client和server的交互使用了一种称作RESP的协议,英文描述:
1 2 3 | A client connects to a Redis server creating a TCP connection to the port 6379 . While RESP is technically non-TCP specific, in the context of Redis the protocol is only used with TCP connections<br> (or equivalent stream oriented connections like Unix sockets). |
大意是使用了TCP连接,但是没有使用tcp协议,我们编写的代码遵守这个RESP协议。可以看到,在protol层,是没有数据类型的概念的,全部都是以byte数组形式传输。对这个协议进行封装后,就可以像在本地使用redis一样。
熟练使用redis就要对redis的集合特性非常清楚,并且熟悉其命令
1 2 | String:set/get<br>HashMap: hmset/hgetall List:lpush/lrange<br>Set:sadd/smembers<br>ZSet:zadd/zrangebyscore<br># name是其保留字(hold key) |
redis除了常见的集合操作命令外,就是一些功能性的,比如订阅发布系统。在cs模式中,当有消息到达时,服务端要通知客户端,redis集群等。
springboot中集成redis还是相对简单的,AutoRedisConfiguration会自动注入LectureConnectionFactory和RedisTemplate, 但是官方的RedisRemplate默认使用jdk序列化反射,不是很友好,我们可以使用库中的序列化类。
从我的redis使用体验来说,有两个主要问题:一是依赖于键查找,查询功能受限。二是软件小,没有可视化和监控工具,需要非常熟悉命令行,不像mysql数据库,把它当黑盒是不可以的。比如info。
redis还有一个问题就是数据迁移问题,或者谁数据导出,比如格式为json?,数据清理等,都是不太好处理的问题。
redis的键空间如下图所示:
redis在使用过程中要注意的地方:redis默认有16个数据库,就是16个命名空间。默认连接的是0,在使用过程中,要确保连接的是同一个数据库。
redis还有一个大作用是作为分布式锁,可以参考相关的博客实现。
说到redis的持久化,我们必须对计算机的io性能有基本的认识,也是常识。比如我们的wifi网速好的情况下,下载速度10M/s,6G的游戏,大概10min。mac是磁盘是很好的,读写速度大概500m/s-1000m/s,普通的linux服务器,使用dd命令,测出磁盘大概300M/s。 在RDB持久化时,如果数据达到了3000M,就需要10s,还是影响用户体验的,所以一般选择aof的范式持久化。我们可以使用pidstat命令查看。serverCron自动触发的持久化,是以bgsave命令执行的,所以基本不影响读写性能,但是rdb的触发触发时机,决定了会丢失部分数据,但是加载快。
如果同时开启了rdb和aof持久化,redis重启时会加载哪个呢?答案是aof,为什么这么设计,主要是aof数据完整。rdb一般会有几十分钟,几小时的数据丢失。
在redis中,如何理解hash表。有两个要把握,1、底层存储方式是数组,2、通过散列函数O(1)找元素。在hash中,都可能存在键冲突,解决键冲突就有几种,比如链地址法,再哈希法(使用新的hash函数)等。同时,当hash表的负载因子过大或者过小时,需要rehash。rehash一般需要调整hash函数和数组长度,其存储空间一般有两种方式,1、原理空间上修改的。2、者重新分配空间。
redis中的一些数据结构:Intset(整数键)--->(退化) hashtable。在redis字符串操作中,可以使用incr和decr操作,完成整数的操作。在redisTemplate中,提供了getAndSet函数,返回之前的值。所以要知道现在的值,还是get一下。
参考博文:
《redis设计和实现》
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
2019-05-02 软件工程中的若干实用性原则
2018-05-02 服务器端推送技术