您现在的位置是:网站首页 > 心得笔记
redis中string的常见业务场景(1)
一. string类型
1.数据结构
redis的string数据结构是一种基础的键值对类型。
key
的值。如果key
已经存在,这个命令会更新它的值。SET myKey "myValue"
GET key - 获取与key
关联的值。
GET myKey
key
。DEL myKey
INCR key - 将key
中的数值增加1。如果key
不存在,它将首先被设置为0。
INCR myKey
DECR key - 将key
中的数值减少1。
DECR myKey
2.场景应用
2.1.缓存功能
string类型常用于缓存经常要访问的数据,以提高接口响应速度和降低数据库的压力。
衍生问题:redis作为缓存使用时,如何避免数据的不一致性问题
解决方案1:队列+重试机制
采用队列和重试机制实现数据库和缓存间数据的最终一致性。
基本思路:
1.更新数据库数据 当应用程序需要对数据进行更新时,首先更新数据库中的数据。 数据库更新操作完成后,记录该操作的信息,包括操作类型、操作的数据ID等。 2.将操作信息放入消息队列 将数据库操作信息封装成消息,并放入消息队列中。 消息队列可以选择高可靠性的消息中间件,如RocketMQ、Kafka等。 3. 异步消费消息并处理缓存 创建一个异步的消费者服务,从消息队列中读取消息。 根据消息中的操作类型和数据ID,对缓存进行相应的操作。例如,如果消息是删除操作,则尝试删除缓存中对应的数据。 可使用supervisor监听。 4. 实现重试机制 如果缓存操作失败(如删除缓存失败),则将该消息重新放入消息队列中,并设置一个重试次数或重试间隔。 消费者服务在读取消息时,会检查消息的重试次数或重试间隔,如果未达到限制,则重新尝试对缓存进行操作。 如果重试多次后仍然失败,则可以将该消息记录到日志中,并通知相关开发人员进行处理。
解决方案2:基于订阅binlog的异步更新缓存
通过监听MySQL的binlog日志,异步消费者消费日志并更新到Redis;
读取binlog后分析 ,利用消息队列,推送更新各台的redis缓存数据。 这样一旦MySQL中产生了新的写入、更新、删除等操作,就可以把binlog相关的消息推送至Redis, Redis再根据binlog中的记录,对Redis进行更新。 这里的消息推送工具可以采用第三方:kafka、rabbitMQ等来实现推送更新Redis。
2.2.计数器
利用INCR
和DECR
命令,String类型可以作为计数器使用,适用于统计如网页访问量、商品库存数量等 。
衍生问题:通过redis实现博客的文章浏览次数
解决方案:使用Redis的INCR命令原子性地递增文章的浏览次数,定期将浏览次数同步到数据库,用于历史数据分析。
2.3.分布式锁
通过SETNX
命令(仅当键不存在时设置值),String类型可以实现分布式锁,保证在分布式系统中的互斥访问 。
衍生问题:在分布式系统中,如电商的秒杀活动或库存管理,如何确保同一时间只有一个进程或线程可以修改共享资源,以避免数据不一致的问题。
解决方案:使用Redis的SETNX命令实现分布式锁的获取和释放,通过Lua脚本确保释放锁时的原子性,并在执行业务逻辑前尝试获取锁,业务逻辑执行完毕后确保释放锁,从而保证在分布式系统中对共享资源的安全访问。
$lockCacheKey = config('cache.prefix').':agent_batch_apply:'.$agentId; //选择数据库 Redis::select(2); $orderLock = Redis::setnx($lockCacheKey, 1);//为1,则表示获取锁成功,为0表示锁已被其他进程持有 if($orderLock === 0){ //锁失败 // 防止死锁 if(Redis::ttl($lockCacheKey) == -1){ Redis::expire($lockCacheKey, 10); } throw new CommonException("请勿重复提交!"); } Redis::expire($lockCacheKey, 10);//设置过期时间 //TODO 业务逻辑
2.4.限流
使用EXPIRE
命令,结合INCR
操作,可以实现API的限流功能,防止系统被过度访问 。
衍生问题:在高流量期间,接口收到大量并发请求,这可能会导致后端服务压力过大,甚至崩溃,怎么限流
解决方案:请求计数+设置过期时间+检查请求频率
1.请求计数:每次API请求时,使用INCR命令对特定的key进行递增操作。 2.设置过期时间:使用EXPIRE命令为计数key设置一个过期时间,过期时间取决于限流的时间窗口(例如1秒)。 3.检查请求频率:如果请求计数超过设定的阈值(例如每秒100次),则拒绝新的请求或进行排队
2.5.共享session
在多服务器的Web应用中,用户在不同的服务器上请求时能够保持登录状态,实现会话共享。
衍生问题:分布式架构中,如何实现session共享
解决方案:使用Redis的String类型来集中存储和管理用户session信息。
1.存储session:当用户登录成功后,将用户的唯一标识sessionid和用户信息序列化后存储在redis。 2.验证session:每次用户请求时,通过请求中的session ID从Redis获取session信息,验证用户状态。 3.更新Session:用户活动时,更新Redis中存储的session信息,以保持其活跃状态。 4.过期策略:设置session信息在Redis中的过期时间,当用户长时间不活动时自动使session失效。
3.注意事项
1.String类型的值可以是任何形式的文本或二进制数据,最大容量为512MB 。 2.在使用String类型作为计数器时,应确保操作的原子性,避免并发访问导致的数据不一致 。 3.使用分布式锁时,要注意锁的释放和超时机制,防止死锁的发生 。 4.存储对象时,应考虑序列化和反序列化的成本,以及数据的压缩和安全性 。 5.在使用String类型作为缓存时,需要合理设置过期时间,以保证数据的时效性 。