您的位置:首页 > 游戏 > 手游 > 苏州技术馆网站建设_噼哩噼哩pilipili污染版_东莞网站推广策划_百度seo排名查询

苏州技术馆网站建设_噼哩噼哩pilipili污染版_东莞网站推广策划_百度seo排名查询

2024/12/22 23:49:34 来源:https://blog.csdn.net/2302_79741013/article/details/143996485  浏览:    关键词:苏州技术馆网站建设_噼哩噼哩pilipili污染版_东莞网站推广策划_百度seo排名查询
苏州技术馆网站建设_噼哩噼哩pilipili污染版_东莞网站推广策划_百度seo排名查询

1. Redis 大 Key 问题

原因
  • 内存占用:大 Key 占用大量内存,可能导致 Redis 服务器内存不足。
  • 性能影响
    • 删除操作:删除大 Key 时,Redis 需要释放大量内存,这可能阻塞其他操作。
    • 过期操作:大 Key 过期时,同样会阻塞 Redis 服务器。
    • 持久化操作:在进行 RDB 或 AOF 持久化时,大 Key 会增加持久化文件的大小,延长持久化时间。
  • 网络传输:大 Key 在网络传输时会占用大量带宽,影响其他数据的传输效率。
解决方案
  1. 拆分数据:将大 Key 拆分成多个小 Key,减少单个 Key 的内存占用。
  2. 使用过期时间:为大 Key 设置合理的过期时间,避免长时间占用内存。
  3. 优化数据结构:选择合适的数据结构来存储数据,例如使用 zset 替代 list,使用 hash 替代多个 string
  4. 定期清理:定期检查和清理不再需要的大 Key。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;
import java.util.UUID;@Service
public class BigKeySplitterService {@Autowiredprivate StringRedisTemplate stringRedisTemplate;private static final int CHUNK_SIZE = 1000; // 每个分片的最大大小/*** 将大 Key 拆分成多个小 Key** @param bigKey 大 Key* @param values 大 Key 对应的值列表*/public void splitBigKey(String bigKey, List<String> values) {int totalChunks = (int) Math.ceil((double) values.size() / CHUNK_SIZE);for (int i = 0; i < totalChunks; i++) {int start = i * CHUNK_SIZE;int end = Math.min(start + CHUNK_SIZE, values.size());List<String> chunk = values.subList(start, end);String chunkKey = bigKey + ":chunk:" + i;stringRedisTemplate.opsForList().rightPushAll(chunkKey, chunk);}}/*** 合并多个小 Key 为一个大 Key** @param bigKey 大 Key* @return 合并后的值列表*/public List<String> mergeChunks(String bigKey) {List<String> result = new ArrayList<>();int i = 0;while (true) {String chunkKey = bigKey + ":chunk:" + i;List<String> chunk = stringRedisTemplate.opsForList().range(chunkKey, 0, -1);if (chunk.isEmpty()) {break;}result.addAll(chunk);i++;}return result;}
}

2. Redis 热 Key 问题

原因
  • 高并发访问:某些 Key 被大量请求访问,导致 Redis 服务器负载过高。
  • 性能瓶颈:热 Key 可能成为性能瓶颈,影响整个系统的响应速度。
解决方案
  1. 数据分片:将数据分布在多个 Redis 实例上,减轻单个实例的负载。
  2. 缓存层:在 Redis 前面增加一层缓存,例如使用本地缓存或 CDN 缓存。
  3. 限流:对热 Key 的访问进行限流,避免过多请求同时打到 Redis 上。
  4. 预热:提前加载热 Key,避免冷启动时的高负载。

数据分片:将数据分布在多个 Redis 实例上,减轻单个实例的负载。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;import java.util.HashMap;
import java.util.Map;@Service
public class DataShardingService {@Autowiredprivate Map<Integer, StringRedisTemplate> redisTemplates;/*** 初始化 Redis 实例映射*/@Autowiredpublic void initRedisTemplates() {redisTemplates = new HashMap<>();// 假设我们有3个 Redis 实例redisTemplates.put(0, new StringRedisTemplate()); // 配置 Redis 实例1redisTemplates.put(1, new StringRedisTemplate()); // 配置 Redis 实例2redisTemplates.put(2, new StringRedisTemplate()); // 配置 Redis 实例3}/*** 根据 Key 的哈希值选择 Redis 实例** @param key 键* @return 选择的 Redis 实例*/public StringRedisTemplate selectRedisInstance(String key) {int hash = key.hashCode();int instanceIndex = Math.abs(hash % redisTemplates.size());return redisTemplates.get(instanceIndex);}/*** 存储数据** @param key   键* @param value 值*/public void setData(String key, String value) {StringRedisTemplate redisTemplate = selectRedisInstance(key);redisTemplate.opsForValue().set(key, value);}/*** 获取数据** @param key 键* @return 值*/public String getData(String key) {StringRedisTemplate redisTemplate = selectRedisInstance(key);return redisTemplate.opsForValue().get(key);}
}

使用 Redis 的原子递增操作来实现限流。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;@Service
public class RateLimiterService {@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 限流逻辑** @param key      限流的键* @param limit    限流阈值* @param duration 限流时间窗口(秒)* @return 是否超过限制*/public boolean isRateLimited(String key, int limit, int duration) {String rateLimitKey = "rate_limit:" + key;long count = stringRedisTemplate.opsForValue().increment(rateLimitKey, 1);if (count == 1) {stringRedisTemplate.expire(rateLimitKey, duration, TimeUnit.SECONDS);}return count > limit;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com