记录一次处理redis异常的文章

博客讲述了Redis抛出异常,提示无法在磁盘持久保存,查看日志发现是磁盘写入错误、无剩余空间。经检查,系统硬盘已满,原因是抓取图片占用大量空间,且服务器两块硬盘只挂载了一块。最终通过挂载第二块硬盘、迁移图片,使Redis恢复正常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

抛出异常是这个样子的:

edis.exceptions.ResponseError: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.

(edis.exceptions.responseerror:misconf redis被配置为保存RDB快照,但目前无法在磁盘上持久保存。可以修改数据集的命令被禁用,因为此实例被配置为在RDB快照失败时报告写入过程中的错误(在bgsave错误选项上停止写入)。有关RDB错误的详细信息,请查看redis日志。)

好的,来看一下redis的日志文件,vim /usr/local/redis/var/redis.log 

931:M 23 May 2019 10:56:34.647 # Background saving error
931:M 23 May 2019 10:56:34.747 * 1 changes in 900 seconds. Saving...
931:M 23 May 2019 10:56:34.755 * Background saving started by pid 23534
23534:C 23 May 2019 10:56:39.787 # Write error saving DB on disk: No space left on device

提示:保存数据库时,在磁盘上写入错误,设备上没有剩余空间,

我们来看一下磁盘使用情况 (系统是centos7)    df -h

Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        36G   34G  160M 100% /

原来真的是硬盘满了,因为最近在做抓取图片的工作,看了一下已抓取的图片,已经下了23G。

最坑的是,看了一下服务器配置是两块硬盘,一块40G,一块200G, 只挂载了一块。

好吧,把第二块硬盘挂载上,迁移图片, redis恢复正常。

 

 


 

 

 

### SpringBoot 和 Redis 实现文章浏览量统计 为了实现文章浏览量的记录功能,可以借助 Redis 的 HyperLogLog 数据结构来去重并计算独立访客的数量(UV),同时也可以简单地使用字符串类型的键值对来累加总访问次数(PV)。以下是具体的实现方式: #### 1. 使用 HyperLogLog 记录 UV Redis 提供了 `PFADD` 命令用于向 HyperLogLog 中添加元素,而 `PFCOUNT` 则用来获取当前集合中的近似唯一值数量。这种方式非常适合处理高并发场景下的 UV 统计。 ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; @Service public class ArticleService { @Autowired private StringRedisTemplate redisTemplate; public void recordArticleView(String articleId, String userIp) { // 定义 key,例如:"article:uv:{articleId}" String uvKey = "article:uv:" + articleId; // 添加 IP 地址到 HyperLogLog 结构中 redisTemplate.opsForHyperLogLog().add(uvKey, userIp); // 更新 PV (Page View),定义 key 如:"article:pv:{articleId}" String pvKey = "article:pv:" + articleId; redisTemplate.opsForValue().increment(pvKey); // 自增操作 } public long getUniqueViews(String articleId) { // 获取 UV 数量 String uvKey = "article:uv:" + articleId; return redisTemplate.opsForHyperLogLog().size(uvKey); } public long getTotalViews(String articleId) { // 获取 PV 总数 String pvKey = "article:pv:" + articleId; Object totalViewsObj = redisTemplate.opsForValue().get(pvKey); if (totalViewsObj != null && !"".equals(totalViewsObj.toString())) { return Long.parseLong(totalViewsObj.toString()); } return 0L; // 如果不存在返回默认值 0 } } ``` 上述代码实现了两个主要的功能: - **recordArticleView**: 每次有新的页面访问时调用此方法,传入文章 ID (`articleId`) 和用户 IP (`userIp`) 来记录一次访问行为。 - **getUniqueViews**: 返回指定文章的独立访客数量(UV)[^1]。 - **getTotalViews**: 返回指定文章的总访问次数(PV)。 #### 2. 处理定时任务同步数据至数据库 为了避免频繁读写数据库带来的性能瓶颈,可以在夜间或其他低峰期通过定时任务将 Redis 中的数据持久化到关系型数据库中。 ```java import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class DataSyncTask { @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨两点执行 public void syncDataToDatabase() { // 查询所有文章的 PV 和 UV 并保存到数据库 List<String> allArticles = getAllArticleIdsFromRedis(); // 获取所有文章ID列表 for (String articleId : allArticles) { long pv = articleService.getTotalViews(articleId); long uv = articleService.getUniqueViews(articleId); saveToDatabase(articleId, pv, uv); // 调用 DAO 方法保存到 DB } } private List<String> getAllArticleIdsFromRedis() { Set<String> keys = redisTemplate.keys("article:*"); return new ArrayList<>(keys.stream() .map(k -> k.replace("article:", "")) .collect(Collectors.toSet())); } private void saveToDatabase(String articleId, long pv, long uv) { // TODO: 实现具体逻辑,将数据插入或更新到数据库表中 } } ``` 这段代码展示了如何设置一个定时器,在每天固定时间触发并将 Redis 中的文章浏览统计数据批量导入数据库。 #### 3. 缓存优化与异常保护 考虑到实际生产环境可能会遇到诸如缓存穿透、缓存雪崩等问题,因此还需要采取一些额外措施保障系统的稳定性。比如可以通过为每个缓存 Key 设置带有随机偏移量的有效期限来减少集中过期的风险;另外还可以引入熔断机制防止突发流量冲击下游服务[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值