


最终基本上实现了这个功能,当时也做了一个基于 SpringBoot 的 Demo ,后来又改了一版基于 Jedis 版本的,因为可以自己定义和操作多线程,更加灵活自由的实现一些细节。
最近提离职后正在交接期,自己的时间比较多,又翻出这个早起的 Demo ,想改造一下,用到我的心情记录员项目中,如果精力和时间有的话我更想将它完善为一个完整的、可复用的项目。
心情记录员小程序为什么要用到这个?以及为什么不用其他成熟的 RabbitMQ ,首先不用其他成熟的原因是我不想搞太多中间件,一个项目中 Redis 安装是大多数情况,因此我想在保持单体应用的基础上实现一个 MQ ,另外的一个原因就是折腾,这也是我本人的一个“缺点”,什么都喜欢自己折腾一下,验证可行性。接下来说说应用场景吧,心情记录员这款小程序目前调用的 AI 是 Kimi 的平台,目前因为是前期,因此是免费版本,并发数限制到了 1 ,这就会导致一个问题,如果同时有两个或者多个(意淫一下,哈哈哈)同时点了记录的时候,这时候有一个肯定会报错,这时候就可以用到消息队列了,将请求的数据先放入队列,等前一个 AI 生成结束后再次调用,就这?……,一个队列不就搞定了吗?当然还有场景了,那就是目前 AI 生成我采用的是 Stream 流式返回,而我是在点击记录后就开始生成,点击记录后会跳转到结果页面,为了使用户跳过去立马就感觉到在生成,因此我就将调用 AI 接口的动作提前到跳转页面前点击记录按钮后,然后给一定到 Loading 延迟在跳转,跳转到结果页后建立 WebSocket 连接,根据 openId 标识接收消息,这时候这个消息其实已经在上一步中在生成了,这里就可以用到消息队列了,根据对应的 openId 到消息队列中取内容,服务端的 WebSocket 只需要根据标识从消息队列中缓存的生成结果进行返回即可,提升了响应速度。
大概流程就像下图这样:
4 年前这个项目的库和博客:
Gitee-redismq (原谅我以前使用 Gitee 的行为,哈哈哈)
]]>这两个系统虽然几乎没什么人用了,但需要的时候可以自取,已开源: https://github.com/Jobcrazy/Redis-WinLegacy
]]>如题
]]>HEXPIRE and HPEXPIRE:设置秒级和毫秒级生存时间HEXPIREAT and HPEXPIREAT:设置秒级和毫秒级 UNIX 过期时间戳HPERSIST:移除过期时间HEXPIRETIME and HPEXPIRETIME:获取秒级和毫秒级 UNIX 过期时间戳HTTL and HPTTL:获取秒级和毫秒级生存时间https://github.com/redis/redis/releases/tag/7.4-rc1
这么多年了,终于来了
]]>难道每次执行什么 get,set 操作,都会检测一遍密码吗? 我理解不能像 mysql 一样,有个连接池,初始化一些长连接,之后就不用再认证/鉴权什么的了

难道要用 C# 跑测试才能发挥 Garnet 的性能? https://microsoft.github.io/garnet/docs/benchmarking/results-resp-bench
]]>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 内存都没解决。
]]>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());
]]>而且还有个好处就是避免了常说的“缓存一致性问题”😄。
各位大佬厂里有没有这样用的?如果没有原因是什么呢?
]]> 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
]]>唯一的一次,还是自己 py 程序的问题,原因记不清楚了,好像是自己往 redis 里面写日志,忘了设置过期时间了.
还是就是 celery 用 redis 做 broker,会断联的问题,但是这个 python 单线程遇到 pub/sub 导致的,redis 还是稳
]]>https://github.com/hcymysql/redis_monitor
Redis Monitor 可以监控单机模式,哨兵模式,集群模式,并且录入一个主库或者从库 IP ,自动发现主库或者从库 IP 信息,无需人工再次录入。
采用远程连接方式获取数据,所以无需要在 Redis 服务器端部署相关 agent 或计划任务,可实现微信和邮件报警。
注:监控环境为 Redis 6.2 以上版本。
]]>然后主节点自动都转移到了其中一台机器上,此时 kill 掉这台机器,发现集群无法恢复,貌似是没法投票了。
应该如何避免这种情况发生呢?
]]>现在偶尔会出现一个问题:执行第 2 步操作时,有时候校验 ticket 会不通过
排查一下: redis 主从偏移有点大,造成主从数据不一样,校验接口走从库时查询不到 ticket 所以校验失败,大概是网络原因?
想到的一个解决方案是,校验接口强制走主库,但是哨兵模式下主库是不固定,有啥办法强制走主库吗( Java 语言的 SDK )?
或者有更好的解决方案?
]]>出现的情况是有时候 B 已经将数据写入 redis 了,但是 A 读不到. 查询写入使用的同一个 StringRedisTemplate.
有时候查不到就很迷
顺便吐槽下华为云 -- huaweicloud.csdn.net
点下阅读全文就自动获取手机号发送注册验证码..
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 中给的答案不一样
]]>cacheKey + "_id",value 是随机数,expireTime=10 秒,若 key 已存在则失败),若生成 leaseId 失败则等待并重试。cacheKey + "_id"、value=leaseId 的值)cacheKey + "_id"的值)这样有什么问题吗?
]]>因为用户的客户端不可信,有几个问题不知道如何解决,独立的临时账号解决了客户端的安全问题,那么主要是客户端的资源占用的限制上。
暂时只想到这些,恳求各位赐教!
]]>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 使用时有什么注意事项?
]]>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 也是一样的效果, 不知道大家有没有解决过一样的问题?