Redis way to explore https:https://cdn.v2ex.com/navatar/67c6/a1e7/47_normal.png?m=1608052197 https:https://cdn.v2ex.com/navatar/67c6/a1e7/47_large.png?m=1608052197 2025-03-31T04:04:31Z Copyright © 2010-2018, V2EX Redis 运行一段时间后报错导致挂掉,有什么办法解决呢? tag:www.v2ex.com,2025-03-31:/t/1122194 2025-03-31T02:37:06Z 2025-03-31T04:04:31Z Geekerstar member/Geekerstar
1:C 31 Mar 2025 10:15:53.909 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see
https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1:C 31 Mar 2025 10:15:53.909 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 31 Mar 2025 10:15:53.909 * Redis version=7.4.1, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 31 Mar 2025 10:15:53.909 * Configuration loaded
1:M 31 Mar 2025 10:15:53.909 * monotonic clock: POSIX clock_gettime
1:M 31 Mar 2025 10:15:53.910 # Failed to write PID file: Permission denied
1:M 31 Mar 2025 10:15:53.910 * Running mode=standalone, port=6379.
1:M 31 Mar 2025 10:15:53.910 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 31 Mar 2025 10:15:53.910 * Server initialized
1:M 31 Mar 2025 10:15:53.910 * Reading RDB base file on AOF loading...
1:M 31 Mar 2025 10:15:53.910 * Loading RDB produced by version 7.4.1
1:M 31 Mar 2025 10:15:53.910 * RDB age 159448 seconds
1:M 31 Mar 2025 10:15:53.910 * RDB memory usage when created 3.08 Mb
1:M 31 Mar 2025 10:15:53.910 * RDB is base AOF
1:M 31 Mar 2025 10:15:53.915 * Done loading RDB, keys loaded: 1103, keys expired: 0.
1:M 31 Mar 2025 10:15:53.916 * DB loaded from base file appendonly.aof.12754.base.rdb: 0.006 seconds
1:M 31 Mar 2025 10:15:54.042 # Bad file format reading the append only file appendonly.aof.12754.incr.aof: make a backup of your AOF file, then use ./redis-check-aof --fix <filename.manifest> ]]> Redis Stream 实现 MQ 的可行性 tag:www.v2ex.com,2025-02-27:/t/1114525 2025-02-27T02:01:59Z 2025-06-02T09:19:46Z xiaohupro member/xiaohupro 早在 4 年前,当我发现 Redis5 中增加了 Stream 类型后我就觉得它的这些特性完全可以实现一个完整的 MQ 中间件功能,当时我还在交控工作,当时的项目刚好涉及到大量数据入库的一个需求,当时这个项目不算很大,所以我就想把这个新的技术引入到项目中,实现一个轻量级的基于 Redis 的消息队列。

最终基本上实现了这个功能,当时也做了一个基于 SpringBoot 的 Demo ,后来又改了一版基于 Jedis 版本的,因为可以自己定义和操作多线程,更加灵活自由的实现一些细节。

最近提离职后正在交接期,自己的时间比较多,又翻出这个早起的 Demo ,想改造一下,用到我的心情记录员项目中,如果精力和时间有的话我更想将它完善为一个完整的、可复用的项目。

心情记录员小程序为什么要用到这个?以及为什么不用其他成熟的 RabbitMQ ,首先不用其他成熟的原因是我不想搞太多中间件,一个项目中 Redis 安装是大多数情况,因此我想在保持单体应用的基础上实现一个 MQ ,另外的一个原因就是折腾,这也是我本人的一个“缺点”,什么都喜欢自己折腾一下,验证可行性。接下来说说应用场景吧,心情记录员这款小程序目前调用的 AI 是 Kimi 的平台,目前因为是前期,因此是免费版本,并发数限制到了 1 ,这就会导致一个问题,如果同时有两个或者多个(意淫一下,哈哈哈)同时点了记录的时候,这时候有一个肯定会报错,这时候就可以用到消息队列了,将请求的数据先放入队列,等前一个 AI 生成结束后再次调用,就这?……,一个队列不就搞定了吗?当然还有场景了,那就是目前 AI 生成我采用的是 Stream 流式返回,而我是在点击记录后就开始生成,点击记录后会跳转到结果页面,为了使用户跳过去立马就感觉到在生成,因此我就将调用 AI 接口的动作提前到跳转页面前点击记录按钮后,然后给一定到 Loading 延迟在跳转,跳转到结果页后建立 WebSocket 连接,根据 openId 标识接收消息,这时候这个消息其实已经在上一步中在生成了,这里就可以用到消息队列了,根据对应的 openId 到消息队列中取内容,服务端的 WebSocket 只需要根据标识从消息队列中缓存的生成结果进行返回即可,提升了响应速度。

大概流程就像下图这样: 心情记录员.drawio.png

4 年前这个项目的库和博客:

Gitee-redismq (原谅我以前使用 Gitee 的行为,哈哈哈)

CSDN 博客(如果对 CSDN 排斥可以访问下面我自己网站的文章)

个人网站文章地址

]]>
Redis 缓存数据 tag:www.v2ex.com,2025-01-22:/t/1107082 2025-01-22T07:13:19Z 2025-01-22T09:15:05Z nitouge member/nitouge 目前使用 Redis 缓存数据,对于 A 和 B 单独缓存,现在有其他服务需要 A 和 B 两个对象的某些属性 问题:

  1. 存数据在服务消费方还是服务提供方;
  2. 存组合对象,A,B 对象更新,组合对象都需要去更新或者删除再加载;
  3. 对于分页查询或者 list 查询后,缓存每一条数据,如果通过注解,是否需要详情接口,再去缓存,而不是直接缓存集合数据
]]>
支持 WinXP/2003 的 Redis 服务端 tag:www.v2ex.com,2024-11-25:/t/1092511 2024-11-25T09:16:57Z 2024-12-03T18:51:17Z Jobcrazy member/Jobcrazy 因近期我做的一个项目需要,修改出来了一个适配 winxp 和 2003 的 32 位 redis-server ,可以用参数正常安装为系统服务。

这两个系统虽然几乎没什么人用了,但需要的时候可以自取,已开源: https://github.com/Jobcrazy/Redis-WinLegacy

]]>
怎么才能学好 redis,有什么好的教程或者 blog 推荐吗? tag:www.v2ex.com,2024-10-11:/t/1079248 2024-10-11T07:59:36Z 2024-10-11T15:26:28Z Rust2015 member/Rust2015 一直不得法,十分郁闷。求推荐。

如题

]]>
线上服务 redis 查询超时排查求教 tag:www.v2ex.com,2024-07-17:/t/1058091 2024-07-17T10:25:58Z 2024-07-17T11:08:52Z a1oyss0925 member/a1oyss0925 一年前给某单位做了个门户类的服务,SpringBoot 项目,单节点 redis 、mysql 当时就是几个人瞎写,堆成一堆屎山,现在不知道为什么几乎每隔一两周 redis 都会查询超时,服务报错: java.lang.RuntimeException: org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 10 second(s) 稍微有点头绪的话就是有个功能会往 redis 里存大量的数据,使用的是 map ,并且取的频率还是挺高的,但是不知道该怎么确定就是这个错,没法找到证据 线上排错这方面自己也没经验,请问应该怎么入手

]]>
有木有安卓 app 的 client 端呀? tag:www.v2ex.com,2024-07-06:/t/1055361 2024-07-06T14:24:57Z 2024-07-06T16:56:36Z 1140601003 member/1140601003 除了 Tiny RDM 之外还有什么比较好用的 Redis GUI 工具么? tag:www.v2ex.com,2024-06-19:/t/1050747 2024-06-19T01:39:26Z 2024-06-19T04:47:56Z jamfer member/jamfer
所以请问还有其他好用的 Redis GUI 工具么? ]]>
Redis 支持 Hash 字段单独设置过期时间 tag:www.v2ex.com,2024-06-07:/t/1047578 2024-06-07T01:43:11Z 2024-06-07T02:14:28Z LeegoYih member/LeegoYih Redis 7.4-rc1 引入了 9 个新命令:

https://github.com/redis/redis/releases/tag/7.4-rc1

这么多年了,终于来了

]]>
Redis 加上密码后,整体性能下降 20%? tag:www.v2ex.com,2024-05-12:/t/1040022 2024-05-12T09:19:17Z 2024-05-13T04:40:55Z cuishuang member/cuishuang 这太震惊了...(图片来自极客时间 安全攻防技能 30 讲)

难道每次执行什么 get,set 操作,都会检测一遍密码吗? 我理解不能像 mysql 一样,有个连接池,初始化一些长连接,之后就不用再认证/鉴权什么的了

]]>
新学 redis 集群的疑惑 tag:www.v2ex.com,2024-05-08:/t/1038852 2024-05-08T09:59:45Z 2024-04-28T10:02:27Z miaeLKK member/miaeLKK Garnet 真比 Redis 快吗? tag:www.v2ex.com,2024-04-27:/t/1036125 2024-04-27T06:10:26Z 2024-04-27T12:56:40Z keakon member/keakon 用 Docker 跑了下 redis-benchmark:

难道要用 C# 跑测试才能发挥 Garnet 的性能? https://microsoft.github.io/garnet/docs/benchmarking/results-resp-bench

]]>
Redis 几乎每小时都出现大量超时,求助 tag:www.v2ex.com,2024-04-22:/t/1034586 2024-04-22T05:35:22Z 2024-04-22T20:31:17Z drymonfidelia member/drymonfidelia 报错信息是 Timeout awaiting response (outbound=1KiB, inbound=0KiB, 5728ms elapsed, timeout is 5000ms), command=SET, next: EVAL, inst: 0, qu: 0, qs: 15, aw: False, bw: SpinningDown, rs: ReadAsync, ws: Idle, in: 76, in-pipe: 0, out-pipe: 0, serverEndpoint: 127.0.0.1:6379, mc: 1/1/0, mgr: 10 of 10 available, clientName: AppProductionEnvServer1(SE.Redis- v2.5.43.42402), IOCP: (Busy=0,Free=10000,Min=9000,Max=10000), WORKER: (Busy=236,Free=32531,Min=10000,Max=32767), POOL: (Threads=236,Queueditems=50,Completeditems=8751117254), v: 2.5.43.42402 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts)

出错的时候看了下也就三百多并发,比较怀疑是下面这段代码引起的:

 while (!await redis.GetDatabase().LockTakeAsync($"PlaceOrder:{user.UserId}", "1", TimeSpan.FromSeconds(180))) { await Task.Delay(1); } 

作用是确保同一用户只有一个订单未写入数据库(系统下单逻辑涉及几十个函数,全是一些莫名奇妙的判断逻辑,混淆后可读性大幅提升的那种(当然是开玩笑的)),屎山作者已经跑路了,没人能看懂他代码,一个用户下多个订单数据会混乱。更牛逼的这套系统除了性能极差,运行 3 年没出错一次。一次调用 API 只能下一单,客户端随硬件交付,已经写死了,不能更新,然后客户端一次多少个订单就多少并发调用 API 提交,没有队列功能。目前要求 500 订单 10 秒内全部下单完成返回订单号(单独提交的话每个订单 0.01 秒左右能写入完数据拿到订单号)。

预分配订单号行不通,不运行一遍这部分屎山代码不能确定这个订单能不能提交,返回订单号就代表这个订单提交成功了,不能取消。目前打算改造成 Sub/Pub ,不知道能不能提升性能,或者 V 友有没有更好的改造方案?只要能让这屎山跑起来就行,代码多脏都没关系,改动需要尽可能小,不能把系统改炸。目前加硬件到 256GB 内存都没解决。

]]>
问一下大家 redis 的配置 tag:www.v2ex.com,2024-04-15:/t/1032530 2024-04-15T02:28:55Z 2024-04-15T03:17:02Z Gocobnus member/Gocobnus 一般大家是用 redis client 本身的超时、重试配置,还是会自己包装一下

]]>
Redis 怎样将字节串传递给 lua 脚本? tag:www.v2ex.com,2024-03-30:/t/1028440 2024-03-30T12:51:01Z 2024-02-29T12:48:01Z itx10237 member/itx10237 struct PersonInfo { int age; char addr[10]; };

PersonInfo person_info; person_info.age = 20; strcpy(person_info.addr, "sz");

redisContext * cc;

std::string name = "JACK";

如果要将上面的 name 和 person_info 传给 lua 脚本,应该怎么做呢? 下面的写法是不完整的, 但是又不知道该怎么写才对.

redisCommand(cc, "EVALSHA %s 1 %s", "redis 返回的 lua 脚本 sha1 值", name.c_str());

]]>
微软 Garnet 的发展前景如何,有没有可能替代 Redis? tag:www.v2ex.com,2024-03-28:/t/1027820 2024-03-28T08:13:18Z 2024-05-15T11:11:12Z huangsijun17 member/huangsijun17 有人跑了压测,在 Redis 每秒数十万次的设备上,Garnet 可以达到每秒八千完次。也有人说 Garnet 不支持 Redis 的一些函数 lua ,包括经典的分布式锁。

]]>
业内有没有把 redis 开启 aof=always 当做数据库使用的? tag:www.v2ex.com,2024-03-04:/t/1020312 2024-03-04T01:06:54Z 2024-03-04T10:13:32Z Orlion member/Orlion 个人理解对于简单的存储 kv 、读写压力都比较大的需求,完全可以开启 redis 持久化,当成一个数据库来用的。aof=always 既不会导致数据丢失,也能获取极高的读性能,虽然写性能会变差,但相比 b tree/lsm tree 这种磁盘数据库性能还是比较高的吧。

而且还有个好处就是避免了常说的“缓存一致性问题”😄。

各位大佬厂里有没有这样用的?如果没有原因是什么呢?

]]>
有谁试过 redis 的 string 自增性能吗, 我这怎么是个位数? tag:www.v2ex.com,2024-01-02:/t/1005189 2024-01-02T07:16:22Z 2024-01-13T03:47:58Z bthulu member/bthulu 我一直用这个来生成多个表公用的自增 id. 今天闲来无聊测了下, tps=10, 这有点低的离谱啊 测试代码

 ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); Stopwatch stopwatch = Stopwatch.StartNew(); var count = 100000; for (int i = 0; i < count; i++) { var id = (int)redis.GetDatabase().StringIncrement("PMDCS:id_hello"); } stopwatch.Stop(); Console.WriteLine("用时:" + stopwatch.ElapsedMilliseconds + ", tps=" + (count / stopwatch.ElapsedMilliseconds)); 

测试结果 用时:8357, tps=11

]]>
突然想起一个问题,你们用的 redis 有崩过吗?是什么原因崩的? tag:www.v2ex.com,2023-12-27:/t/1003952 2023-12-27T13:32:08Z 2024-01-10T22:56:51Z chenqh member/chenqh 个人感觉 redis 稳如泰山,完全不会坏,没遇到过 redis 崩的情况

唯一的一次,还是自己 py 程序的问题,原因记不清楚了,好像是自己往 redis 里面写日志,忘了设置过期时间了.

还是就是 celery 用 redis 做 broker,会断联的问题,但是这个 python 单线程遇到 pub/sub 导致的,redis 还是稳

]]>
关联表查询结果的 Redis 缓存如何设计 tag:www.v2ex.com,2023-12-25:/t/1003357 2023-12-25T12:43:16Z 2023-12-25T17:43:16Z 3630cn2023 member/3630cn2023 T2(id, type),两个表关联查询的接口 A(userId),B(projectId),如果用 userId ,projectId 作为两个接口的 Redis 缓存 key ,那么接口 C 用通过表 1 的 id 更新数据的时候,A ,B 接口的 Redis 缓存如何更新? ]]> API 请求如何方便的做并发测试? tag:www.v2ex.com,2023-12-24:/t/1003057 2023-12-24T13:41:45Z 2023-12-24T16:45:23Z quqiu member/quqiu 现在基于 redis 写了读锁的模块,想做个并发测试。 现在是直接浏览器开 F12 ,跑一次请求,然后复制 CURL ,写了个 BASH 来多并发跑这段 CURL 。 有没有更方便点的工具各位大佬教教。

]]>
请教兄弟们一个问题, datagrip 连接 redis 如何显示 redis 键的 过期时间呢? tag:www.v2ex.com,2023-12-23:/t/1002887 2023-12-23T10:14:25Z 2023-12-24T05:33:18Z wuyiccc member/wuyiccc 目前我的 datargip 版本是 2023.3.2 ]]> 关于 Redis RESP3 的想法 tag:www.v2ex.com,2023-12-13:/t/1000021 2023-12-13T06:15:02Z 2023-12-13T06:15:02Z hulk member/hulk https://mp.weixin.qq.com/s/NZbo8-01aX7K-3Ba7XC10A

]]>
轻便式 Redis Monitor 面向研发人员图形可视化监控平台 tag:www.v2ex.com,2023-12-04:/t/997370 2023-12-04T01:23:51Z 2023-12-03T21:23:51Z hcymysql member/hcymysql 轻便式 Redis Monitor 面向研发人员图形可视化监控平台,借鉴了 LEPUS(天兔)监控平台以及 redis-cli info 命令输出的监控指标项,去掉了一些不必要看不懂的监控项,目前采集了数据库连接数、QPS 、内存使用率统计和同步复制延迟时长,以及列出当前所有慢查询命令。

https://github.com/hcymysql/redis_monitor

Redis Monitor 可以监控单机模式,哨兵模式,集群模式,并且录入一个主库或者从库 IP ,自动发现主库或者从库 IP 信息,无需人工再次录入。

采用远程连接方式获取数据,所以无需要在 Redis 服务器端部署相关 agent 或计划任务,可实现微信和邮件报警。

注:监控环境为 Redis 6.2 以上版本。

视频演示: https://www.bilibili.com/video/BV1UC4y1A7F8/

]]>
Redis 中使用 pipeline 执行命令时,有单次执行数量的限制吗? tag:www.v2ex.com,2023-11-29:/t/996334 2023-11-29T11:35:29Z 2023-11-29T19:04:51Z Ackvincent member/Ackvincent 通过 scan 方法获取 1W 个 key 的名字,然后使用 pipeline 执行 memory_usage 命令获取这 1W 个 key 占用空间的大小,这样会对服务器造成很大压力吗?现在在测试服务器上执行感觉没什么压力,不知道生产环境下,会不会有影响。 谢谢

]]>
[故障模拟]redis cluster 3 机 3 主 6 从,主节点都转移到了其中一台机器上,然后这台机器宕机 tag:www.v2ex.com,2023-11-17:/t/992960 2023-11-17T16:32:08Z 2023-11-17T17:52:29Z joyanhui member/joyanhui 本来是 三台机器 分别有一个主节点的,反复删除过几次节点也重启过几次机器。

然后主节点自动都转移到了其中一台机器上,此时 kill 掉这台机器,发现集群无法恢复,貌似是没法投票了。

应该如何避免这种情况发生呢?

]]>
你们现在连接 redis 集群是用的什么工具,可以分享一下下载链接吗? tag:www.v2ex.com,2023-11-15:/t/992205 2023-11-15T10:18:11Z 2023-11-15T10:15:11Z Janice06 member/Janice06 我自己连接工具是用的 dbeaver ,但是 dbeaver 好像不能连接 redis 集群

]]>
求教一下 Redis 哨兵模式下,主从延迟问题 tag:www.v2ex.com,2023-11-14:/t/991788 2023-11-14T05:01:52Z 2023-11-14T07:27:32Z zhongpingjing member/zhongpingjing 具体场景:

  1. 有个单点登录 CAS 服务,其他服务登录时会请求一个 ticket ,CAS 服务颁发完 ticket 后,会写入 redis 。
  2. 其他服务获取到 ticket 后,会调用 CAS 服务的另一个接口去校验 ticket ,同时获取用户信息。

现在偶尔会出现一个问题:执行第 2 步操作时,有时候校验 ticket 会不通过

排查一下: redis 主从偏移有点大,造成主从数据不一样,校验接口走从库时查询不到 ticket 所以校验失败,大概是网络原因?

想到的一个解决方案是,校验接口强制走主库,但是哨兵模式下主库是不固定,有啥办法强制走主库吗( Java 语言的 SDK )?

或者有更好的解决方案?

]]>
想问下大佬 40M 的字符串适合放到 redis 缓存吗? tag:www.v2ex.com,2023-11-11:/t/991060 2023-11-11T15:16:09Z 2023-11-12T00:38:19Z pppwww member/pppwww 想问下大佬们 40M 的字符串适合放到 redis 缓存吗?如果不适合的话怎么解决呢

]]>
redis 有时取不到值 tag:www.v2ex.com,2023-11-10:/t/990742 2023-11-10T08:51:03Z 2023-11-11T04:25:36Z cMoon member/cMoon 背景: A 调用服务 B,然后每秒查一次 redis 去获取值. B 收到 A 的请求后将数据写入 redis.

出现的情况是有时候 B 已经将数据写入 redis 了,但是 A 读不到. 查询写入使用的同一个 StringRedisTemplate.

有时候查不到就很迷


顺便吐槽下华为云 -- huaweicloud.csdn.net
点下阅读全文就自动获取手机号发送注册验证码..

]]>
redis 集群中 执行事务 或者 lua 脚本 涉及到多个 key 时,这些 key 要求在同一个节点还是同一个 slot? tag:www.v2ex.com,2023-11-10:/t/990634 2023-11-10T04:20:20Z 2023-11-10T04:27:46Z wqq096737ink member/wqq096737ink
如果这些 key 能够散列在同一个 slot ,那没什么问题。

如果这些 key 之确保散列在同一个节点,可以吗? 大部分博客都只说要求散列在同一个 slot 。

散列在同一个节点会有问题吗? 有没有相关参考文档? ]]>
redis 7 所有命令都是原子的吗? tag:www.v2ex.com,2023-10-30:/t/986619 2023-10-30T02:58:31Z 2023-10-30T08:44:07Z lypdarling member/lypdarling 官网有句话

Redis has a different evolution path in the key-value DBs where values can contain more complex data types, with atomic operations defined on those data types.

是不是所有 redis 7 的命令都是原子的?这跟 chatgpt 中给的答案不一样

]]>
Redis 是鸡肋吗? tag:www.v2ex.com,2023-10-23:/t/984702 2023-10-23T16:17:34Z 2023-10-23T22:17:34Z justthewayyouare member/justthewayyouare 感觉小项目用处不大

]]>
Redis 服务挂了,一段时间后又恢复,不会造成缓存与数据库不一致吗? tag:www.v2ex.com,2023-10-21:/t/984010 2023-10-21T03:27:12Z 2023-10-21T12:34:53Z yodhcn member/yodhcn
如果是 Redis 主从集群,能避免这种情况吗?集群全挂了呢?


注:目前解决缓存与数据库一致所使用的方案,是双写方案,写操作-先写数据库再删缓存,读操作-有缓存就读缓存,无缓存就读数据库后重建缓存

但这种方案的问题是,缓存服务挂了后,在写操作时无法删掉过期缓存,最后等缓存服务恢复,读操作读到的就是过期数据


请老哥们指点一下,
难道因为缓存服务挂掉,就拒绝一切写操作吗? ]]>
为什么 MySQL 有缓存,还要使用 Redis? tag:www.v2ex.com,2023-10-05:/t/979119 2023-10-05T15:48:33Z 2023-10-11T04:14:43Z yodhcn member/yodhcn Q:为什么 MySQL 有缓存,还要使用 Redis ?
A:MySQL 以前有缓存,但由于命中率不高,在新版本中已经舍弃掉了。
Q:那 Oracle 数据库呢? Oracle 数据库有缓存吗?
A:不清楚。
Q:不论是 MySQL 还是 Oracle ,只要是数据库就应该都有缓存,那为什么数据库有缓存,还要使用 Redis ?
A: Redis 支持分片集群,缓存容量容易扩展;而 MySQL 是为单机设计的,缓存容量受限于运行 MySQL 的主机内存。

但面试官好像对这个回答不太满意
现在回想起来,虽然当时是我混淆了“MySQL 查询缓存”和“MySQL 的 Buffer Pool”,但是,MySQL 的 Buffer Pool 也起到了缓存作用,减少磁盘 IO 。

为什么 MySQL 有缓存,还要使用 Redis ?
这个问题,目前我只想到从两个角度回答:
1. Redis 支持分片集群,缓存容量容易扩展。
2. 多级缓存。Redis 内存->Buffer Pool->磁盘。
各位还有什么别的看法吗? ]]>
关于缓存一致性问题,不知道我这个方案是否可行 tag:www.v2ex.com,2023-09-20:/t/975618 2023-09-20T09:46:05Z 2023-09-20T12:09:02Z xing393939 member/xing393939 数据库和缓存的数据一致性问题是 Web 开发中经常碰到的,一般我们都是采用 cache aside 方案,比如这篇文章介绍的。最近参考Scaling Memcache at Facebook,我想到了一个基于 redis 的简化版本,不知是否可行,希望大家帮忙参考下:

  1. cacheMiss 时,生成一个对应 cacheKey 的 leaseId ( redis 生成一个值:key 是cacheKey + "_id",value 是随机数,expireTime=10 秒,若 key 已存在则失败),若生成 leaseId 失败则等待并重试。
  2. cacheMiss 后,先查 db 再更新缓存,但更新缓存的时候,需要检查 leaseId 是否有效( redis 是否存在 key=cacheKey + "_id"、value=leaseId 的值)
  3. 每次更新 db 后,删除缓存,同时删除 leaseId ( redis 删除 key=cacheKey + "_id"的值)

这样有什么问题吗?

]]>
redis 集群获取不到连接 tag:www.v2ex.com,2023-08-18:/t/966351 2023-08-18T02:51:40Z 2023-08-18T03:49:40Z smartxia member/smartxia 我们线上有个服务,用的是 tomcat 集群部署,session 放在 redis cluster 里面,目前启动了 6 台节点。最近突然有某个节点从连接池拿不到资源,似乎都是在获取用户信息那里报错的,基本上都是提示:JedisException: Could not get a resource from the pool ,NoSuchElementException: Timeout waiting for idle object ;我们用的是 jedis2.9.0 ,基于 commons-pool2 的连接池,在网上搜索类似的问题都说是 jedis 版本问题,把 2.9.1 回退到 2.9.0 ,结果这不是巧了,我们用的就是 2.9.0 ,也报这个错。奇怪的就是 6 台 tomcat 就其中一台报错了,之前是 maxTotal=1000 ,maxIdle=200 ,后来 2 个都改成了 200 ,重启后,过了 1 天又换了一台 tomcat 继续报这个错,大佬们有没有啥方案?

]]>
用 redis 直接替换 app/物联网的 mq 服务器的可行性大吗?怎么对客户端进行限制 tag:www.v2ex.com,2023-08-15:/t/965630 2023-08-15T16:27:17Z 2023-08-18T15:37:54Z joyanhui member/joyanhui 现有方案是 mqtt 服务器。 但是今天仔细看了了一下 redis7 的 acl 控制。感觉权限可以缩小到很小 。另外 Stream 结构可以直接用 redis 解决消息持久化的问题。 所以在琢磨用 redis 直接做 mq 服务器。不再经过 mqtt 转发一次浪费性能。 直接给每一个用户的客户端分配一个 redis 账号,账号定时横换。

因为用户的客户端不可信,有几个问题不知道如何解决,独立的临时账号解决了客户端的安全问题,那么主要是客户端的资源占用的限制上。

暂时只想到这些,恳求各位赐教!

]]>
redis 怎么裁剪 zset 只保留排名前 100 的数据 tag:www.v2ex.com,2023-08-03:/t/962146 2023-08-03T09:12:04Z 2023-08-03T09:45:14Z ben548 member/ben548 缓存失效后先返回再触发更新的场景要怎么处理? tag:www.v2ex.com,2023-07-26:/t/960000 2023-07-26T11:59:39Z 2023-07-26T18:39:13Z ben548 member/ben548 我想的方案:
往消息队列里面发消息的方式,但是多用户并发的情况下,其实会有多个用户过来请求更新缓存,当然可以用分布式锁来处理,只让一个用户生成缓存成功。
这个就是我的一个想法,有没有更好的方案? ]]>
关于 redis 一个小问题(随机性) tag:www.v2ex.com,2023-07-22:/t/958903 2023-07-22T17:31:36Z 2023-07-23T04:43:21Z golangggg member/golangggg 自己有 10 个代理 ip, 想均匀的使用 ( 轮训着用 一个接着一个 循环往复)
使用过两种方案
1.ip 存为 set 类型 每次使用 srandmember 随机抽取, 但测试发现 非常不随机
2.ip 存为 list 类型 每次 rpoplpush 到同一队列, 这个可以实现完全平均的使用,但有个问题无法解决, 因为可能某一个 ip 某短时间不可以使用, 需要从队列中移除, 但是使用 list 无法移除某一个失效的 ip
想问下大佬们 有什么好的解决方案吗 ]]>
求教大佬,线上 redis cluster 中适合使用 redis lua script 吗?以及使用时有什么注意事项? tag:www.v2ex.com,2023-07-18:/t/957661 2023-07-18T04:02:30Z 2023-07-18T01:54:03Z ryan961 member/ryan961 我将一部分逻辑代码通过 lua 脚本实现,变相的实现原子操作(如下),但之前使用 lua 脚本是遇到过 not in the same slot 的错误,感觉我的这个脚本可能与会遇到。如果我真的通过 key 加前缀的方式保证他们在同一个 slot 内是不是也会导致 cluster 处于一个不健康的集群状态。

local userAttributiOnKey= KEYS[1]; local humeSource = KEYS[2]; local attributeKeys = cjson.decode(KEYS[3]); if redis.call("EXISTS", userAttributionKey) == 1 then -- get attribution cache local res = redis.call("GET", userAttributionKey); if res then return { 1, res }; end end local matchResult = {}; local hits = {}; local latestTime = 0; for i = 1, #attributeKeys do local indexInfoString = redis.call("GET", attributeKeys[i]); if indexInfoString then local indexInfo = cjson.decode(indexInfoString); local reportSource = indexInfo['report_source']; local uniqId = indexInfo['uniq_id']; local timestamp = tonumber(indexInfo['timestamp']); if humeSource == '' or humeSource == indexInfo['report_source'] then -- check attribute index info if reportSource ~= '' and uniqId ~= '' then if timestamp > latestTime then indexInfo['hit'] = attributeKeys[i]; indexInfo['match_res'] = 'matched'; matchResult = indexInfo; latestTime = timestamp; end table.insert(hits, attributeKeys[i]); else return redis.error_reply("Invalid Info:" .. indexInfoString); end end -- delete attribute key cache redis.call("DEL", attributeKeys[i]) end end if #hits > 0 then matchResult['hits'] = hits; local matchResultStr = cjson.encode(matchResult); -- set attribution cache redis.call("SET", userAttributionKey, matchResultStr, "EX", ARGV[1]); return { 1, matchResultStr }; end return { 0, cjson.encode(matchResult) }; 

请教下大佬和前辈,我这是不是一种错误的使用方式?以及 lua script 使用时有什么注意事项?

]]>
怎么使用命令批量删除匹配的 key 值? tag:www.v2ex.com,2023-07-14:/t/956790 2023-07-14T08:17:18Z 2023-07-14T13:50:59Z JimmyChan1506 member/JimmyChan1506 使用下面的命令可以查到一堆 key

redis-cli -a myPassword -h redis-host -p 6379 --scan --pattern '*myKey*' 

但使用下面的命令,却无法删除成功

redis-cli -a myPassword -h redis-host -p 6379 --scan --pattern '*myKey*' | xargs redis-cli -a myPassword -h redis-host -p 6379 unlink (integer) 0 

当然了, 把 unlink 改成 del 也是一样的效果, 不知道大家有没有解决过一样的问题?

]]>
对 redis 的 zset 做分片的时候怎么选择分片个数 tag:www.v2ex.com,2023-07-08:/t/955072 2023-07-08T04:09:50Z 2023-07-08T10:42:55Z ben548 member/ben548 现状:关注人数存在 redis 的 zset 中,每个活动有一个独立的 zset 。发送 push 消息通知的时候,是分页遍历 zset ,逐个发送通知。可能在关注数超百万的时候需要较长的处理时间(比如超过 5 分钟)。
要求:希望在推送消息时尽可能的快,低延时。
为了达到这个要求,选择对 zset 做分片,分片的规则是:按订阅用户的 userid 做 hash 取值,取值结果按分片数取模,在分配到相应的 zset 分片上。
问题:zset 数据除了承担 push 消息通知的数据源之外,还用于查询用户是否订阅该活动的状态查询(这个没啥问题,找到对应的分片,然后查询 zscore 即可)和订阅总数计算的角色。如果我为了某些活动可能超过百万的关注订阅数,而设置 1024 个 zset 分片,是不是意味着绝大多数的活动,为了计算总数都要去做 1024 次 zcount 再将 result 相加才能得到结果?感觉也不是很好的设计。。。。(当然也可以总数单独维护,不通过 zset 分片结果相加获取,就是这样又增加了存储成本)
大家觉得该怎么做比较合适呢? ]]>
关于消息推送方案的讨论 tag:www.v2ex.com,2023-07-04:/t/953983 2023-07-04T06:32:30Z 2023-07-04T11:01:56Z ben548 member/ben548 当前方案:创建完活动之后向延迟队列中投递一个执行时间为(活动开始时间-15 分钟)的任务,目前关注用户存储在 redis 的 zset 中,向延迟队列中投递的是活动的 id 信息,延迟队列消费到这条消息的时候,从关注的用户 zset 中拉取用户 id 进行消息推送。
延迟队列的设计:目前是依赖 redis ,生产者向 redis 的 zset 中投递 task 信息,score 是活动的通知时间(活动开始时间-15 分钟),然后轮询这个 task 的 redis key ,读取到期是任务信息,读取到之后将该任务信息投递到 redis 的 list (通过 rpush )中,消费者则一直读取这个 list 队列(通过 lpop )。
目前想探讨的是:这个方案是否在活动很多的时候导致推送消息的延迟(虽然可以通过增加消费者来缓解,正常哪怕是一个活动有百万级别的活动关注者(极其罕见),从 redis 的 zset 中分页拉取出来并投递消息,一般处理时长不会超过 10 分钟)
但是隐隐约约还是觉得是不是还有更好的方案呢?可以尽量减少延迟的方案。 ]]>
Redis 的 zset 按 score 排序做分页的时候怎么保证数据不丢失? tag:www.v2ex.com,2023-06-26:/t/951909 2023-06-26T15:26:13Z 2023-06-27T00:45:04Z ben548 member/ben548 redis 的 zset 如果打散成多个 zset 的话,如果要分页查询怎么处理呢? tag:www.v2ex.com,2023-06-25:/t/951425 2023-06-25T04:32:42Z 2023-06-25T07:45:01Z ben548 member/ben548 第一页是很容易的,比如一页 10 条,每一个 zset 都查出 top 10 然后合并排序一下即可
但是第二页和第三页却不能这么处理,因为直接从各个 zset 中获取排名 10 到 20 的 value ,来做排序合并得到的结果并不准确
能想到的一个方案是把所有的 zset 都合并成一个总的 zset 再来分页切割,但是感觉这样太耗费性能了,不是一个好的方案。 ]]>
关于社区场景下,用户已读文章不再推荐这种需求实现方案的探讨 tag:www.v2ex.com,2023-06-06:/t/946461 2023-06-06T21:12:15Z 2023-06-07T02:44:55Z ben548 member/ben548 用户签到页面,为用户推荐后台配置好的文章内容,按发布时间倒叙排列(数据存储在 redis 的 zset 中,score 是文章发布时间,value 是文章 id ),并且可以认为被推荐的内容数量有上限限制(不多于 1000 条),用户已阅的数据不再推荐给用户,直到所有的内容被推荐完,再从头开始再推荐一遍,一直循环下去。
实现方案:
一般涉及到这种需求,都会想到用布隆过滤器或者 bitmap 来实现,我最终选择了用布隆过滤器,不用 bitmap 的主要原因是:
1.目前 post_id 的值是雪花算法生成的,长度有 16 位,如果不做处理直接把这个 id 当成 bitmap 的 offset 会造成极大的内存空间浪费,而怎么把这些 post_id 转换成更小的从 1 开始递增的数字,处理起来比较麻烦(不是不可以,自己想到的就有几种,比如说:因为展示的内容都是关联了某些 tag 的内容,用数据库里面的关联关系表的 id 作为 bitmap 的 offset 来处理是可以做到的,之所以不选择 bitmap 最主要还是下面的原因 2 );
2.getbit 不支持批量查询(当然我知道有人可能要说可以用 lua 脚本,用 pipeline 之类的,但是写起来有点麻烦)而选择布隆过滤器就没有上面这两个问题了
这次选用的是直接装 redis 的布隆过滤器模块,实现方案如下:
1.每个用户初始化一个 500 长度的布隆过滤器,用户已阅的内容通过 bf.add 操作加入他的布隆过滤器中
2.获取列表数据的时候,按下面的步骤进行:
2.1 从 zset 中读取 100 条数据,
2.2 通过 bf.mexist 操作查询这些内容是否已阅,已阅的内容跳过
2.3 一直循环 2.1 和 2.2 步骤,直到查到满足条目数的内容为止(目前是定的 12 条一页)
2.4 如果 zset 查到最后都没有得到满足条件的条目数,则返回经过了 2.1 和 2.2 步骤之后获取到的数据(可能有数据,只是不满足 12 条的条件,总数记为 total1 )+zset 中按发布时间顺序倒序获取 12-total1 条数据作为补充 2.5 什么时候删除用户的布隆过滤器? 2.4 步骤中发现 total1 的数量为 0 (说明所有内容都已经阅读过了)时进行删除
内存占用估算:有试过模拟一个 500 长度 size 的布隆过滤器大致的内存占用为 800 多个字节,按 50w 日活来计算的话,总的占用空间为两三百 M 左右,在可接受范围内,但是如果为每个用户初始化 1000 长度 size 的布隆过滤器,内存占用就有点高了,初步预估在 900M 左右
我的疑问:
1.其实用布隆过滤器的方案,有通过 golang 自己依赖 redis 的 bitmap 结构实现一个的方案也有直接用 redis 的布隆过滤器模块(需要编译安装)的方案,我好奇哪种方案更好?
2.上面说到的获取列表数据的逻辑,总感觉是不是有什么地方可以优化,因为按上面描述的逻辑,每一次都要遍历一遍 zset 中的数据,最差的情况下,会有数十次的 redis 查询(比如最后一页)
3.可能有人会说可以用 bf.count 看用户已阅内容的总数,因为总是最新的内容展示出来,那么直接跳过 bf.count 的总数去获取数据即可,就不用那么麻烦,但是这样获取有个问题,就是新加入 zset 的内容(而且发布时间还是最新的),按这个方案来处理,几乎无法得到展示(只有等内容耗尽,到下一轮推荐才能展示)
4.这个列表是展示在用户签到的下方内容推荐的模块中,我在想每个用户的布隆过滤器初始长度设置为多少比较合适,一开始想着直接设置 1000 的长度,但是想到真实的场景,用户可能签完到就离开了,不会去消费内容(虽然不会主动下拉消费,但是底部会外漏出 2 到 4 条内容出来,也被认为是用户已阅的内容),所以直接初始化 1000 长度我感觉有点浪费,所以考虑先初始化 500 个,消费内容超过 500 个的话,Redis 的布隆过滤器会自动扩容,扩容成自己的 2 倍内存空间(试过,这种扩容最终占的内存空间会比一开始就初始化 1000 长度的内存空间占用大很多),不知道这么设计是否合适?以上就是我个人的一些实现方案的想法和探索,大家有什么观点和看法,欢迎评论留言一起探讨一下 ]]>
一个 abtest 实验中 redis 设计的思考 tag:www.v2ex.com,2023-06-05:/t/946008 2023-06-05T09:21:29Z 2023-06-06T04:24:20Z ben548 member/ben548 需求:需要将用户分成 abcd 四个桶,不同桶内用户看到的信息不同,第一次分桶时需要将分桶结果发送给数据部门。
实现:将用户 id 经过 murmurhash 计算出来的哈希结果按 4 取模,得到分桶信息,将该结果保持到 redis 中,每个用户一个 redis key ,字符串类型存储,如 abresult_11111(user_id):1,程序开始执行时先读取 redis ,如果存在分桶记录,那么直接返回,不存在则进行分桶操作,并将分桶结果发给数据部门

疑问:
目前这个设计是一个好的设计吗?百万级别的用户量的话,是不是会生成百万的 redis key ,印象中 redis_key 过多不是一个好的设计,比如不好管理等。
我能想到的几个问题:
1.印象中用 hash 结构来存储,会被这种存储方式节约内存,但是用 hash 来存储必然导致 big key 问题,当然在这种场景下面,不涉及像 getall 那样的 O(n)操作,是不是 big key 问题可以基本忽略不计?印象中 big key 可能导致的问题不止是性能问题,还有像数据倾斜导致的访问倾斜问题等,所以用 hash 来存储的话是不是也要那用户 id 来做分片才是比较合适的方案?
2.redis 的删除是惰性删除+定时删除,定时删除基于取样,取样的话如果失效的数据过多,印象中会一直不断的循环删除,指定取样的结果不满足为止,想知道这个定时删除是在主进程上完成的吗?如果过多的 key 失效,会阻塞 redis 进程吗?

大佬们,一起讨论下啊?一个是上面提出的一些问题,还有就是如果是你们来设计的话会怎么设计? ]]>
redis 获取不到链接的异常 tag:www.v2ex.com,2023-03-19:/t/925265 2023-03-19T04:52:53Z 2023-03-19T08:21:23Z rqxiao member/rqxiao java 应用,生产者单线程分页查询数据库并写入 redis 队列中,消费者 30 个线程多线程消费 list 。本来是没有出现过这个报错的,但是更新了生产者的 sql 后,sql 速度变快了?每次正常运行一段时间后,生产者异常就出现,消费者也接着出现异常

报的异常如下

生产者异常: :"sendQueueMessageInfo leftPushAll : 异常 : org.springframework.data.redis.RedisConnectionFailureException: Unexpected end of stream.; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream. org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:67) org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:41) org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44) org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42) org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:142) org.springframework.data.redis.connection.jedis.JedisListCommands.convertJedisAccessException(JedisListCommands.java:486) org.springframework.data.redis.connection.jedis.JedisListCommands.lPush(JedisListCommands.java:84) org.springframework.data.redis.connection.DefaultedRedisConnection.lPush(DefaultedRedisConnection.java:444) org.springframework.data.redis.core.DefaultListOperations.lambda$leftPushAll$2(DefaultListOperations.java:124) org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224) org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:184) org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:95) org.springframework.data.redis.core.DefaultListOperations.leftPushAll(DefaultListOperations.java:124) com.service.ds.exec.DataSourceActuator.sendQueueMessageInfo(DataSourceActuator.java:392) com.service.ds.exec.DataSourceActuator.execAndPushQueue(DataSourceActuator.java:214) com.controller.rest.etl.EtlTaskRestController$1.run(EtlTaskRestController.java:86) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) java.lang.Thread.run(Thread.java:745)\

Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream. redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:199) redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40) redis.clients.jedis.Protocol.process(Protocol.java:153) redis.clients.jedis.Protocol.read(Protocol.java:218) redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:341) redis.clients.jedis.Connection.getIntegerReply(Connection.java:266) redis.clients.jedis.BinaryJedis.lpush(BinaryJedis.java:1119) org.springframework.data.redis.connection.jedis.JedisListCommands.lPush(JedisListCommands.java:82)\n\t... 12 more\n","stackTrace":"","reqId":"","elapsedTime":null}

消费者异常: 1","className":"com.service.schedule.SchedulerTask$1","lineNumber":"63","message":"队列消费 : 异常 : org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:281) org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:464) org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:132) org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:95) org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:82) org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:211) org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:184) org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:95) org.springframework.data.redis.core.DefaultListOperations.leftPush(DefaultListOperations.java:99) com.service.etl.consumer.QueueConsumer.retryQueueMessage(QueueConsumer.java:101) com.service.etl.consumer.QueueConsumer.consume(QueueConsumer.java:180) com.service.schedule.SchedulerTask$1.run(SchedulerTask.java:60) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)java.lang.Thread.run(Thread.java:745)\nCaused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the poolredis.clients.util.Pool.getResource(Pool.java:53)redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)redis.clients.jedis.JedisPool.getResource(JedisPool.java:16) org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:271)\n\t... 14 more\nCaused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection resetredis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:202) redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40) redis.clients.jedis.Protocol.process(Protocol.java:153) redis.clients.jedis.Protocol.read(Protocol.java:218) redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:341) redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:240) redis.clients.jedis.BinaryJedis.auth(BinaryJedis.java:2223) redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:108) org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:889) org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:424) org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:349) redis.clients.util.Pool.getResource(Pool.java:49)\n\t... 17 more\nCaused by: java.net.SocketException: Connection reset java.net.SocketInputStream.read(SocketInputStream.java:209) java.net.SocketInputStream.read(SocketInputStream.java:141) java.net.SocketInputStream.read(SocketInputStream.java:127) redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:196)\n\t... 28 more\n","stackTrace":"","reqId":"","elapsedTime":null}

redis 配置

public RedisTemplate<String, QueueMessageInfo> redisQueueMessageTemplate(RedisConnectionFactory factory) { RedisTemplate<String, QueueMessageInfo> template = new RedisTemplate<String, QueueMessageInfo>(); template.setConnectionFactory(factory); // 使用 Jackson2JsonRedisSerializer 来序列化和反序列化 redis 的 value 值 Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<Object>(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); serializer.setObjectMapper(om); template.setValueSerializer(serializer); template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.afterPropertiesSet(); return template; } @Bean public RedisConnectionFactory connectionFactory() { JedisPoolConfig poolCOnfig= new JedisPoolConfig(); poolConfig.setMaxTotal(maxActive); poolConfig.setMaxIdle(maxIdle); poolConfig.setMaxWaitMillis(maxWait); poolConfig.setMinIdle(minIdle); poolConfig.setTestOnBorrow(true); poolConfig.setTestOnReturn(false); poolConfig.setTestWhileIdle(true); JedisClientConfiguration jedisClientCOnfiguration= null; if (ssl) { jedisClientCOnfiguration= JedisClientConfiguration.builder().usePooling().poolConfig(poolConfig).and() .readTimeout(Duration.ofMillis(timeout)).useSsl().build(); } else { jedisClientCOnfiguration= JedisClientConfiguration.builder().usePooling().poolConfig(poolConfig).and() .readTimeout(Duration.ofMillis(timeout)).build(); } RedisStandaloneConfiguration redisStandalOneConfiguration= new RedisStandaloneConfiguration(); redisStandaloneConfiguration.setDatabase(redisDatabase); redisStandaloneConfiguration.setPort(port); redisStandaloneConfiguration.setPassword(password); redisStandaloneConfiguration.setHostName(host); RedisConnectionFactory redisCOnnectionFactory= new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration); logger.info("初始化 redis 链接池 : JedisPoolConfig"); return redisConnectionFactory; } # 池在给定时间可以分配的最大连接数。使用负值无限制。 #spring.redis.pool.max-active=200 spring.redis.pool.max-active=200 # 池中“空闲”连接的最大数量。使用负值表示无限数量的空闲连接。 # spring.redis.pool.max-idle=20 spring.redis.pool.max-idle=20 # 连接分配在池被耗尽时抛出异常之前应该阻塞的最长时间量(以毫秒为单位)。使用负值可以无限期地阻止。 spring.redis.pool.max-wait=9000 # 目标为保持在池中的最小空闲连接数。这个设置只有在正面的情况下才有效果。 #spring.redis.pool.min-idle=20 spring.redis.pool.min-idle=20 
]]>
ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86