自动做简历的网站,十堰微网站建设费用,wordpress创建表格,软件开发要多少钱Redis应用笔记 一、 前言二、 Redis八种常用数据类型2.1 Redis的五种基本数据类型2.2 Redis的三种特殊数据类型 三、发现Redis热Key方案3.1 使用 Redis 自带的 --hotkeys 参数来查找3.2 使用MONITOR 命令3.3 借助开源项目 四、解决 hotkey五、Redis 内存碎片5.1 为何会有Redis … Redis应用笔记 一、 前言二、 Redis八种常用数据类型2.1 Redis的五种基本数据类型2.2 Redis的三种特殊数据类型 三、发现Redis热Key方案3.1 使用 Redis 自带的 --hotkeys 参数来查找3.2 使用MONITOR 命令3.3 借助开源项目 四、解决 hotkey五、Redis 内存碎片5.1 为何会有Redis 内存碎片5.2 查看Redis内存碎片信息5.3 清理 Redis 内存碎片 六、Redis缓存预热6.1 预热工具6.2 启动预热6.2.1 Spring Boot特定逻辑接口6.2.2 使用 InitializingBean 接口6.2.3 使用PostConstruct 注解6.2.4 定时任务预热6.2.5 缓存器预热 一、 前言
夯实Redis基础以及生产环境应用优化的笔记~
二、 Redis八种常用数据类型
5 种基础数据类型String字符串、List列表、Set集合、Hash散列、Zset有序集合。3 种特殊数据类型HyperLogLog基数统计、Bitmap位图、Geospatial (地理位置)。
2.1 Redis的五种基本数据类型
Redis 5 种基本数据类型对应底层数据结构
StringListHashSetZsetSDSLinkedList/ZipList/QuickListDict、ZipListDict、IntsetZipList、SkipList缓存 Session、Token、图片地址、序列化后的对象、计数、分布式锁最新文章、最新动态、消息队列用户信息、商品信息、文章信息、购物车信息网站 UV 统计、文章点赞、动态点赞、共同好友(交集)、共同粉丝(交集)、共同关注(交集)、好友推荐差集、音乐推荐差集、订阅号推荐差集交集、抽奖系统、随机点名排行榜、优先级任务队列
2.2 Redis的三种特殊数据类型
Bitmap 位图HyperLogLog基数统计Geospatial (地理位置)用户签到情况、活跃用户情况、用户行为统计比如是否点赞过某个视频数据量巨大的计数场景热门网站每日/每周/每月访问 ip 数统计、热门帖子 uv 统计需要管理使用地理空间数据的场景附近的人
三、发现Redis热Key方案
3.1 使用 Redis 自带的 --hotkeys 参数来查找
Redis 4.0.3 版本中新增 hotkeys 参数该参数能够返回所有 key 的被访问次数。但会增加 Redis 实例的 CPU 和内存消耗全局扫描因此需要谨慎使用。
使用该方案的前提条件是 Redis Server 的 maxmemory-policy 参数设置为 LFU 算法不否则会报错
Error: ERR An LFU maxmemory policy is not selected, access frequency not tracked. Please note that when switching between policies at runtime LRU and LFU data will take some time to adjust.Redis 中有两种 LFU 算法
volatile-lfuleast frequently used从已设置过期时间的数据集server.db[i].expires中挑选最不经常使用的数据淘汰。allkeys-lfuleast frequently used当内存不足以容纳新写入数据时在键空间中移除最不经常使用的 key。
配置文件 redis.conf 中的示例
# 使用 volatile-lfu 策略
maxmemory-policy volatile-lfu# 或者使用 allkeys-lfu 策略
maxmemory-policy allkeys-lfu3.2 使用MONITOR 命令
MONITOR 命令是 Redis 提供的一种实时查看 Redis 的所有操作的方式可以用于临时监控 Redis 实例的操作情况包括读写、删除等操作。
由于该命令对 Redis 性能的影响比较大因此禁止长时间开启 MONITOR生产环境中建议谨慎使用该命令。
# redis-cli
127.0.0.1:6379 MONITOR
OK
1683638260.637378 [0 172.17.0.1:61516] ping
1683638267.144236 [0 172.17.0.1:61518] smembers mySet
1683638268.941863 [0 172.17.0.1:61518] smembers mySet
1683638269.551671 [0 172.17.0.1:61518] smembers mySet
1683638270.646256 [0 172.17.0.1:61516] ping
1683638270.849551 [0 172.17.0.1:61518] smembers mySet
1683638271.926945 [0 172.17.0.1:61518] smembers mySet
1683638274.276599 [0 172.17.0.1:61518] smembers mySet2
1683638276.327234 [0 172.17.0.1:61518] smembers mySet可以选择在合适的时机短暂执行 MONITOR 命令并将输出重定向至文件在关闭 MONITOR 命令后通过对文件中请求进行归类分析即可找出这段时间中的 hotkey。
3.3 借助开源项目
京东零售的 hotkey 这个项目不光支持 hotkey 的发现还支持 hotkey 的处理。
四、解决 hotkey
读写分离主节点处理写请求从节点处理读请求。使用 Redis Cluster将热点数据分散存储在多个 Redis 节点上。二级缓存hotkey 采用二级缓存的方式进行处理将 hotkey 存放一份到 JVM 本地内存中可以用 Caffeine。
五、Redis 内存碎片
内存碎片可简单理解为不可用的空闲内存。 例如操作系统为任务分配 32 字节的连续内存空间而存储数据实际只需要使用 24 字节内存空间那这多余出来的 8 字节内存空间如果后续没办法再被分配存储其他数据的话就可以被称为内存碎片。 Redis 内存碎片虽然不会影响 Redis 性能但是会增加内存消耗。
5.1 为何会有Redis 内存碎片
1、Redis 存储数据的时候向操作系统申请的内存空间可能会大于数据实际需要的存储空间。Redis官网表明Redis 使用zmalloc方法(Redis自己实现的内存分配方法)进行内存分配的时候除要分配 size 大小的内存之外还会多分配 PREFIX_SIZE 大小的内存。 zmalloc 方法源码
void *zmalloc(size_t size) {// 分配指定大小的内存void *ptr malloc(sizePREFIX_SIZE);if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZEupdate_zmalloc_stat_alloc(zmalloc_size(ptr));return ptr;
#else*((size_t*)ptr) size;update_zmalloc_stat_alloc(sizePREFIX_SIZE);return (char*)ptrPREFIX_SIZE;
#endif
}源码地址https://github.com/antirez/redis-tools/blob/master/zmalloc.c 另外Redis 可使用多种内存分配器来分配内存 libc、jemalloc、tcmalloc默认使用 jemalloc按照一系列固定的大小8 字节、16 字节、32 字节……来分配内存的。
当程序申请的内存大小最接近某个固定值时jemalloc会给它分配相应大小的空间。 例如程序需要申请 17 字节的内存jemalloc会直接给它分配 32 字节的内存这样会导致有 15 字节内存的浪费。 实际jemalloc专门针对内存碎片问题做过优化一般不会存在过度碎片化问题。
2、频繁修改Redis中的数据会产生内存碎片。 Redis官网表明当Redis中的某个数据删除时Redis通常不会轻易释放内存给操作系统。
文档地址https://redis.io/topics/memory-optimization 。
5.2 查看Redis内存碎片信息
使用 info memory 命令即可查看 Redis 内存相关的信息。 Redis官方文档有详细的介绍https://redis.io/commands/INFO 。 Redis 内存碎片率的计算公式
mem_fragmentation_ratio used_memory_rss / used_memory内存碎片率 操作系统实际分配给Redis的物理内存空间大小 / Redis内存分配器为存储数据实际申请使用的内存空间大小内存碎片率的值越大代表内存碎片率越严重那多大的内存碎片率才需要清理呢 通常认为 mem_fragmentation_ratio 1.5 就需要清理内存碎片。mem_fragmentation_ratio 1.5 意味着使用Redis存储实际大小2G的数据需要使用大于3G的内存。 快速查看内存碎片率命令 redis-cli -p 6379 info | grep mem_fragmentation_ratio而碎片率小于 1 时 Redis 内存碎片率低并非只跟 SWAP 有关生产环境通常建议禁用 SWAP。 复制积压缓冲区配置较大、业务数据量较小的情况下极容易造成碎片率 远低于 1这是正常现象无需优化或调整。 通常将线上环境复制缓冲区的值 repl-backlog-size 设置的比较大目的是防止主库频繁出现全量复制而影响性能。 随着业务数据量增长Redis 内存碎片率比值会逐渐趋于 1。
5.3 清理 Redis 内存碎片
Redis4.0-RC3 版本以后自带内存整理可以避免内存碎片率过大的问题。 直接通过 config set 命令将 activedefrag 配置项设置为 yes 即可。
config set activedefrag yes具体清理时间需要通过两个参数控制
# 内存碎片占用空间达到 500mb 的时候开始清理
config set active-defrag-ignore-bytes 500mb
# 内存碎片率大于 1.5 的时候开始清理
config set active-defrag-threshold-lower 50通过 Redis 自动内存碎片清理机制可能会对 Redis 的性能产生影响可通过两个参数来减少对 Redis 性能的影响
# 内存碎片清理所占用 CPU 时间的比例不低于 20%
config set active-defrag-cycle-min 20
# 内存碎片清理所占用 CPU 时间的比例不高于 50%
config set active-defrag-cycle-max 50另外重启节点可以做到内存碎片重新整理。如果采用的是高可用架构的 Redis 集群的话可将碎片率过高的主节点转换为从节点以便进行安全重启。我上月遇到过手工清理效果不佳最后是重启节点解决还是重启大法好使~
六、Redis缓存预热
减少冷启动影响当系统重启或新启动时缓存是空的这被称为冷启动。冷启动可能导致首次请求处理缓慢因为数据需要从慢速存储如数据库检索。提高数据访问速度通过预先加载常用数据到缓存中可以确保数据快速可用从而加快数据访问速度。平滑流量峰值在流量高峰期之前预热缓存可以帮助系统更好地处理高流量避免在流量激增时出现性能下降。保证数据的时效性定期预热可以保证缓存中的数据是最新的特别是对于高度依赖于实时数据的系统。减少对后端系统的压力通过缓存预热可减少对数据库或其他后端服务的直接查询从而减轻负载。
6.1 预热工具
RedisBloomRedisBloom 是 Redis 的一个模块提供多个数据结构包括布隆过滤器、计数器、和 TopK 数据结构等。其中布隆过滤器可以用于 Redis 缓存预热通过将预热数据添加到布隆过滤器中可以快速判断一个键是否存在于缓存中Redis Bulk loading这是一个官方基于 Redis 协议批量写入数据的工具Redis Desktop ManagerRedis Desktop Manager 是一个图形化的 Redis 客户端可以用于管理 Redis 数据库和进行缓存预热。通过 Redis Desktop Manager可以轻松地将预热数据批量导入到 Redis 缓存中。
6.2 启动预热
6.2.1 Spring Boot特定逻辑接口
Spring Boot用于在应用程序启动后执行特定逻辑的接口CommandLineRunner 和 ApplicationRunner。在SpringApplication的 run方法中其实就是 callRunners(context, applicationArguments); 的实现。
private void callRunners(ApplicationContext context, ApplicationArguments args) {ListObject runners new ArrayList();runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());AnnotationAwareOrderComparator.sort(runners);for (Object runner : new LinkedHashSet(runners)) {if (runner instanceof ApplicationRunner) {callRunner((ApplicationRunner) runner, args);}if (runner instanceof CommandLineRunner) {callRunner((CommandLineRunner) runner, args);}}
}可以新建两个类来使用。 MyCommandLineRunner.java
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;Component
public class MyCommandLineRunner implements CommandLineRunner {Overridepublic void run(String... args) throws Exception {// 在应用启动后执行缓存预热逻辑// ...}
}MyApplicationRunner.java
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;Component
public class MyApplicationRunner implements ApplicationRunner {Overridepublic void run(ApplicationArguments args) throws Exception {// 在应用启动后执行缓存预热逻辑// ...}
}6.2.2 使用 InitializingBean 接口
实现 InitializingBean 接口并在 afterPropertiesSet 方法中执行缓存预热的逻辑。这样Spring 在初始化 Bean 时会调用 afterPropertiesSet 方法。
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;Component
public class CachePreloader implements InitializingBean {Overridepublic void afterPropertiesSet() throws Exception {// 执行缓存预热逻辑// ...}
}6.2.3 使用PostConstruct 注解
使用 PostConstruct 注解标注一个方法该方法将在 Bean 的构造函数执行完毕后立即被调用。在这个方法中执行缓存预热的逻辑。
import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;Component
public class CachePreloader {PostConstructpublic void preloadCache() {// 执行缓存预热逻辑// ...}
}6.2.4 定时任务预热
启动预热有个问题就是一旦启动之后如果需要预热新的数据或者需要修改数据就不支持那在应用的运行过程中可通过定时任务来实现缓存的更新预热。 通常依赖这种方式来确保缓存中的数据是最新的避免因为业务数据的变化而导致缓存数据过时。
Scheduled(cron 0 0 1 * * ?) // 每天凌晨1点执行
public void scheduledCachePreload() {// 执行缓存预热逻辑// ...
}也可使用 xxl-job 等定时任务实现。
6.2.5 缓存器预热
有些缓存框架提供缓存加载器的机制可在缓存中不存在数据时自动调用加载器加载数据到缓存中。这样可以简化缓存预热的逻辑。而实际项目中也需要两级缓存增加效率例如我们项目中使用Caffeine实现
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;Service
public class MyCacheService {private final LoadingCacheString, String cache;public MyCacheService() {this.cache Caffeine.newBuilder().refreshAfterWrite(1, TimeUnit.MINUTES) // 配置自动刷新1分钟刷新一次.build(key - loadDataFromSource(key)); // 使用加载器加载数据}public String getValue(String key) {return cache.get(key);}private String loadDataFromSource(String key) {// 从数据源加载数据的逻辑// 这里只是一个示例实际应用中可能是从数据库、外部服务等获取数据System.out.println(Loading data for key: key);return Value for key;}
}使用Caffeine.newBuilder().refreshAfterWrite(1, TimeUnit.MINUTES)配置缓存的自动刷新机制即每个缓存项在写入后的 1 分钟内如果有读请求Caffeine 会自动触发数据的刷新。 loadDataFromSource 方法是用于加载数据的自定义方法。可在此方法中实现从数据源例如数据库、外部服务加载数据的逻辑。 文章转载自: http://www.morning.cykqg.cn.gov.cn.cykqg.cn http://www.morning.zpfqh.cn.gov.cn.zpfqh.cn http://www.morning.nsmyj.cn.gov.cn.nsmyj.cn http://www.morning.xdxpq.cn.gov.cn.xdxpq.cn http://www.morning.ljzqb.cn.gov.cn.ljzqb.cn http://www.morning.qqrlz.cn.gov.cn.qqrlz.cn http://www.morning.yymlk.cn.gov.cn.yymlk.cn http://www.morning.xkzr.cn.gov.cn.xkzr.cn http://www.morning.gllhx.cn.gov.cn.gllhx.cn http://www.morning.bnzjx.cn.gov.cn.bnzjx.cn http://www.morning.sqhlx.cn.gov.cn.sqhlx.cn http://www.morning.tgmfg.cn.gov.cn.tgmfg.cn http://www.morning.nkdmd.cn.gov.cn.nkdmd.cn http://www.morning.tmfm.cn.gov.cn.tmfm.cn http://www.morning.rnrwq.cn.gov.cn.rnrwq.cn http://www.morning.hnkkf.cn.gov.cn.hnkkf.cn http://www.morning.lngyd.cn.gov.cn.lngyd.cn http://www.morning.gcbhh.cn.gov.cn.gcbhh.cn http://www.morning.fsqbx.cn.gov.cn.fsqbx.cn http://www.morning.lbggk.cn.gov.cn.lbggk.cn http://www.morning.kflzy.cn.gov.cn.kflzy.cn http://www.morning.ntgsg.cn.gov.cn.ntgsg.cn http://www.morning.kllzy.com.gov.cn.kllzy.com http://www.morning.mzhhr.cn.gov.cn.mzhhr.cn http://www.morning.xqndf.cn.gov.cn.xqndf.cn http://www.morning.jzykq.cn.gov.cn.jzykq.cn http://www.morning.xkgyh.cn.gov.cn.xkgyh.cn http://www.morning.dbrnl.cn.gov.cn.dbrnl.cn http://www.morning.kmjbs.cn.gov.cn.kmjbs.cn http://www.morning.lkbyj.cn.gov.cn.lkbyj.cn http://www.morning.bxrlt.cn.gov.cn.bxrlt.cn http://www.morning.dxgt.cn.gov.cn.dxgt.cn http://www.morning.pqqhl.cn.gov.cn.pqqhl.cn http://www.morning.nmrtb.cn.gov.cn.nmrtb.cn http://www.morning.lwrks.cn.gov.cn.lwrks.cn http://www.morning.gwjqq.cn.gov.cn.gwjqq.cn http://www.morning.fjtnh.cn.gov.cn.fjtnh.cn http://www.morning.sfphz.cn.gov.cn.sfphz.cn http://www.morning.hbhnh.cn.gov.cn.hbhnh.cn http://www.morning.rmqlf.cn.gov.cn.rmqlf.cn http://www.morning.qxkjy.cn.gov.cn.qxkjy.cn http://www.morning.tftw.cn.gov.cn.tftw.cn http://www.morning.kxqpm.cn.gov.cn.kxqpm.cn http://www.morning.ntgjm.cn.gov.cn.ntgjm.cn http://www.morning.jtdrz.cn.gov.cn.jtdrz.cn http://www.morning.qhfdl.cn.gov.cn.qhfdl.cn http://www.morning.stfdh.cn.gov.cn.stfdh.cn http://www.morning.ie-comm.com.gov.cn.ie-comm.com http://www.morning.guangda11.cn.gov.cn.guangda11.cn http://www.morning.ynryz.cn.gov.cn.ynryz.cn http://www.morning.ssglh.cn.gov.cn.ssglh.cn http://www.morning.gmnmh.cn.gov.cn.gmnmh.cn http://www.morning.brhxd.cn.gov.cn.brhxd.cn http://www.morning.dqrhz.cn.gov.cn.dqrhz.cn http://www.morning.gmdtk.cn.gov.cn.gmdtk.cn http://www.morning.rfwgg.cn.gov.cn.rfwgg.cn http://www.morning.fprll.cn.gov.cn.fprll.cn http://www.morning.spsqr.cn.gov.cn.spsqr.cn http://www.morning.tgyqq.cn.gov.cn.tgyqq.cn http://www.morning.bwkzn.cn.gov.cn.bwkzn.cn http://www.morning.fhrt.cn.gov.cn.fhrt.cn http://www.morning.nkkr.cn.gov.cn.nkkr.cn http://www.morning.ppgdp.cn.gov.cn.ppgdp.cn http://www.morning.qzsmz.cn.gov.cn.qzsmz.cn http://www.morning.lhjmq.cn.gov.cn.lhjmq.cn http://www.morning.rntgy.cn.gov.cn.rntgy.cn http://www.morning.fbhmn.cn.gov.cn.fbhmn.cn http://www.morning.nkjkh.cn.gov.cn.nkjkh.cn http://www.morning.frfpx.cn.gov.cn.frfpx.cn http://www.morning.dnvhfh.cn.gov.cn.dnvhfh.cn http://www.morning.rsjng.cn.gov.cn.rsjng.cn http://www.morning.rwmft.cn.gov.cn.rwmft.cn http://www.morning.kdfqx.cn.gov.cn.kdfqx.cn http://www.morning.zkrzb.cn.gov.cn.zkrzb.cn http://www.morning.jcnmy.cn.gov.cn.jcnmy.cn http://www.morning.rnfn.cn.gov.cn.rnfn.cn http://www.morning.qdlnw.cn.gov.cn.qdlnw.cn http://www.morning.rdlfk.cn.gov.cn.rdlfk.cn http://www.morning.jqjnx.cn.gov.cn.jqjnx.cn http://www.morning.kyytt.cn.gov.cn.kyytt.cn