当前位置: 首页 > news >正文

广州市住房建设部网站企业策划咨询公司

广州市住房建设部网站,企业策划咨询公司,石家庄seo优化公司,管理网站怎么做的这是我的第 43 篇原创文章。Redis 是基于单线程模型实现的#xff0c;也就是 Redis 是使用一个线程来处理所有的客户端请求的#xff0c;尽管 Redis 使用了非阻塞式 IO#xff0c;并且对各种命令都做了优化#xff08;大部分命令操作时间复杂度都是 O(1)#xff09;#… 这是我的第 43 篇原创文章。Redis 是基于单线程模型实现的也就是 Redis 是使用一个线程来处理所有的客户端请求的尽管 Redis 使用了非阻塞式 IO并且对各种命令都做了优化大部分命令操作时间复杂度都是 O(1)但由于 Redis 是单线程执行的特点因此它对性能的要求更加苛刻本文我们将通过一些优化手段让 Redis 更加高效的运行。本文我们将使用以下手段来提升 Redis 的运行速度缩短键值对的存储长度使用 lazy free延迟删除特性设置键值的过期时间禁用长耗时的查询命令使用 slowlog 优化耗时命令使用 Pipeline 批量操作数据避免大量数据同时失效客户端使用优化限制 Redis 内存大小使用物理机而非虚拟机安装 Redis 服务检查数据持久化策略禁用 THP 特性使用分布式架构来增加读写速度。1.缩短键值对的存储长度 键值对的长度是和性能成反比的比如我们来做一组写入数据的性能测试执行结果如下从以上数据可以看出在 key 不变的情况下value 值越大操作效率越慢因为 Redis 对于同一种数据类型会使用不同的内部编码进行存储比如字符串的内部编码就有三种int整数编码、raw优化内存分配的字符串编码、embstr动态字符串编码这是因为 Redis 的作者是想通过不同编码实现效率和空间的平衡然而数据量越大使用的内部编码就越复杂而越是复杂的内部编码存储的性能就越低。这还只是写入时的速度当键值对内容较大时还会带来另外几个问题内容越大需要的持久化时间就越长需要挂起的时间越长Redis 的性能就会越低内容越大在网络上传输的内容就越多需要的时间就越长整体的运行速度就越低内容越大占用的内存就越多就会更频繁的触发内存淘汰机制从而给 Redis 带来了更多的运行负担。因此在保证完整语义的同时我们要尽量的缩短键值对的存储长度必要时要对数据进行序列化和压缩再存储以 Java 为例序列化我们可以使用 protostuff 或 kryo压缩我们可以使用 snappy。2.使用 lazy free 特性 lazy free 特性是 Redis 4.0 新增的一个非常使用的功能它可以理解为惰性删除或延迟删除。意思是在删除的时候提供异步延时释放键值的功能把键值释放操作放在 BIO(Background I/O) 单独的子线程处理中以减少删除删除对 Redis 主线程的阻塞可以有效地避免删除 big key 时带来的性能和可用性问题。lazy free 对应了 4 种场景默认都是关闭的lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no slave-lazy-flush no 它们代表的含义如下lazyfree-lazy-eviction表示当 Redis 运行内存超过 maxmeory 时是否开启 lazy free 机制删除lazyfree-lazy-expire表示设置了过期时间的键值当过期之后是否开启 lazy free 机制删除lazyfree-lazy-server-del有些指令在处理已存在的键时会带有一个隐式的 del 键的操作比如 rename 命令当目标键已存在Redis 会先删除目标键如果这些目标键是一个 big key就会造成阻塞删除的问题此配置表示在这种场景中是否开启 lazy free 机制删除slave-lazy-flush针对 slave(从节点) 进行全量数据同步slave 在加载 master 的 RDB 文件前会运行 flushall 来清理自己的数据它表示此时是否开启 lazy free 机制删除。建议开启其中的 lazyfree-lazy-eviction、lazyfree-lazy-expire、lazyfree-lazy-server-del 等配置这样就可以有效的提高主线程的执行效率。3.设置键值的过期时间 我们应该根据实际的业务情况对键值设置合理的过期时间这样 Redis 会帮你自动清除过期的键值对以节约对内存的占用以避免键值过多的堆积频繁的触发内存淘汰策略。4.禁用长耗时的查询命令 Redis 绝大多数读写命令的时间复杂度都在 O(1) 到 O(N) 之间在官方文档对每命令都有时间复杂度说明地址https://redis.io/commands如下图所示其中 O(1) 表示可以安全使用的而 O(N) 就应该当心了N 表示不确定数据越大查询的速度可能会越慢。因为 Redis 只用一个线程来做数据查询如果这些指令耗时很长就会阻塞 Redis造成大量延时。要避免 O(N) 命令对 Redis 造成的影响可以从以下几个方面入手改造决定禁止使用 keys 命令避免一次查询所有的成员要使用 scan 命令进行分批的游标式的遍历通过机制严格控制 Hash、Set、Sorted Set 等结构的数据大小将排序、并集、交集等操作放在客户端执行以减少 Redis 服务器运行压力删除 (del) 一个大数据的时候可能会需要很长时间所以建议用异步删除的方式 unlink它会启动一个新的线程来删除目标数据而不阻塞 Redis 的主线程。5.使用 slowlog 优化耗时命令 我们可以使用 slowlog 功能找出最耗时的 Redis 命令进行相关的优化以提升 Redis 的运行速度慢查询有两个重要的配置项slowlog-log-slower-than 用于设置慢查询的评定时间也就是说超过此配置项的命令将会被当成慢操作记录在慢查询日志中它执行单位是微秒 (1 秒等于 1000000 微秒)slowlog-max-len 用来配置慢查询日志的最大记录数。我们可以根据实际的业务情况进行相应的配置其中慢日志是按照插入的顺序倒序存入慢查询日志中我们可以使用 slowlog get n 来获取相关的慢查询日志再找到这些慢查询对应的业务进行相关的优化。6.使用 Pipeline 批量操作数据 Pipeline (管道技术) 是客户端提供的一种批处理技术用于一次处理多个 Redis 命令从而提高整个交互的性能。我们使用 Java 代码来测试一下 Pipeline 和普通操作的性能对比Pipeline 的测试代码如下public class PipelineExample {public static void main(String[] args) {Jedis jedis new Jedis(127.0.0.1, 6379);// 记录执行开始时间long beginTime System.currentTimeMillis();// 获取 Pipeline 对象Pipeline pipe jedis.pipelined();// 设置多个 Redis 命令for (int i 0; i 100; i) {pipe.set(key i, val i);pipe.del(keyi);}// 执行命令pipe.sync();// 记录执行结束时间long endTime System.currentTimeMillis();System.out.println(执行耗时 (endTime - beginTime) 毫秒);} } 以上程序执行结果为执行耗时297毫秒普通的操作代码如下public class PipelineExample {public static void main(String[] args) {Jedis jedis new Jedis(127.0.0.1, 6379);// 记录执行开始时间long beginTime System.currentTimeMillis();for (int i 0; i 100; i) {jedis.set(key i, val i);jedis.del(keyi);}// 记录执行结束时间long endTime System.currentTimeMillis();System.out.println(执行耗时 (endTime - beginTime) 毫秒);} } 以上程序执行结果为执行耗时17276毫秒从以上的结果可以看出管道的执行时间是 297 毫秒而普通命令执行时间是 17276 毫秒管道技术要比普通的执行大约快了 58 倍。7.避免大量数据同时失效 Redis 过期键值删除使用的是贪心策略它每秒会进行 10 次过期扫描此配置可在 redis.conf 进行配置默认值是 hz 10Redis 会随机抽取 20 个值删除这 20 个键中过期的键如果过期 key 的比例超过 25% 重复执行此流程如下图所示如果在大型系统中有大量缓存在同一时间同时过期那么会导致 Redis 循环多次持续扫描删除过期字典直到过期字典中过期键值被删除的比较稀疏为止而在整个执行过程会导致 Redis 的读写出现明显的卡顿卡顿的另一种原因是内存管理器需要频繁回收内存页因此也会消耗一定的 CPU。为了避免这种卡顿现象的产生我们需要预防大量的缓存在同一时刻一起过期就简单的解决方案就是在过期时间的基础上添加一个指定范围的随机数。8.客户端使用优化 在客户端的使用上我们除了要尽量使用 Pipeline 的技术外还需要注意要尽量使用 Redis 连接池而不是频繁创建销毁 Redis 连接这样就可以减少网络传输次数和减少了非必要调用指令。9.限制 Redis 内存大小 在 64 位操作系统中 Redis 的内存大小是没有限制的也就是配置项 maxmemory bytes 是被注释掉的这样就会导致在物理内存不足时使用 swap 空间既交换空间而当操心系统将 Redis 所用的内存分页移至 swap 空间时将会阻塞 Redis 进程导致 Redis 出现延迟从而影响 Redis 的整体性能。因此我们需要限制 Redis 的内存大小为一个固定的值当 Redis 的运行到达此值时会触发内存淘汰策略内存淘汰策略在 Redis 4.0 之后有 8 种noeviction不淘汰任何数据当内存不足时新增操作会报错Redis 默认内存淘汰策略allkeys-lru淘汰整个键值中最久未使用的键值allkeys-random随机淘汰任意键值;volatile-lru淘汰所有设置了过期时间的键值中最久未使用的键值volatile-random随机淘汰设置了过期时间的任意键值volatile-ttl优先淘汰更早过期的键值。在 Redis 4.0 版本中又新增了 2 种淘汰策略volatile-lfu淘汰所有设置了过期时间的键值中最少使用的键值allkeys-lfu淘汰整个键值中最少使用的键值。其中 allkeys-xxx 表示从所有的键值中淘汰数据而 volatile-xxx 表示从设置了过期键的键值中淘汰数据。我们可以根据实际的业务情况进行设置默认的淘汰策略不淘汰任何数据在新增时会报错。10.使用物理机而非虚拟机 在虚拟机中运行 Redis 服务器因为和物理机共享一个物理网口并且一台物理机可能有多个虚拟机在运行因此在内存占用上和网络延迟方面都会有很糟糕的表现我们可以通过 ./redis-cli --intrinsic-latency 100 命令查看延迟时间如果对 Redis 的性能有较高要求的话应尽可能在物理机上直接部署 Redis 服务器。11.检查数据持久化策略 Redis 的持久化策略是将内存数据复制到硬盘上这样才可以进行容灾恢复或者数据迁移但维护此持久化的功能需要很大的性能开销。在 Redis 4.0 之后Redis 有 3 种持久化的方式RDBRedis DataBase快照方式将某一个时刻的内存数据以二进制的方式写入磁盘AOFAppend Only File文件追加方式记录所有的操作命令并以文本的形式追加到文件中混合持久化方式Redis 4.0 之后新增的方式混合持久化是结合了 RDB 和 AOF 的优点在写入的时候先把当前的数据以 RDB 的形式写入文件的开头再将后续的操作命令以 AOF 的格式存入文件这样既能保证 Redis 重启时的速度又能减低数据丢失的风险。RDB 和 AOF 持久化各有利弊RDB 可能会导致一定时间内的数据丢失而 AOF 由于文件较大则会影响 Redis 的启动速度为了能同时拥有 RDB 和 AOF 的优点Redis 4.0 之后新增了混合持久化的方式因此我们在必须要进行持久化操作时应该选择混合持久化的方式。查询是否开启混合持久化可以使用 config get aof-use-rdb-preamble 命令执行结果如下图所示其中 yes 表示已经开启混合持久化no 表示关闭Redis 5.0 默认值为 yes。如果是其他版本的 Redis 首先需要检查一下是否已经开启了混合持久化如果关闭的情况下可以通过以下两种方式开启通过命令行开启通过修改 Redis 配置文件开启① 通过命令行开启使用命令 config set aof-use-rdb-preamble yes 执行结果如下图所示命令行设置配置的缺点是重启 Redis 服务之后设置的配置就会失效。② 通过修改 Redis 配置文件开启在 Redis 的根路径下找到 redis.conf 文件把配置文件中的 aof-use-rdb-preamble no 改为 aof-use-rdb-preamble yes 如下图所示配置完成之后需要重启 Redis 服务器配置才能生效但修改配置文件的方式在每次重启 Redis 服务之后配置信息不会丢失。需要注意的是在非必须进行持久化的业务中可以关闭持久化这样可以有效的提升 Redis 的运行速度不会出现间歇性卡顿的困扰。12.禁用 THP 特性 Linux kernel 在 2.6.38 内核增加了 Transparent Huge Pages (THP) 特性 支持大内存页 2MB 分配默认开启。当开启了 THP 时fork 的速度会变慢fork 之后每个内存页从原来 4KB 变为 2MB会大幅增加重写期间父进程内存消耗。同时每次写命令引起的复制内存页单位放大了 512 倍会拖慢写操作的执行时间导致大量写操作慢查询。例如简单的 incr 命令也会出现在慢查询中因此 Redis 建议将此特性进行禁用禁用方法如下echo never  /sys/kernel/mm/transparent_hugepage/enabled为了使机器重启后 THP 配置依然生效可以在 /etc/rc.local 中追加 echo never /sys/kernel/mm/transparent_hugepage/enabled。13.使用分布式架构来增加读写速度 Redis 分布式架构有三个重要的手段主从同步哨兵模式Redis Cluster 集群使用主从同步功能我们可以把写入放到主库上执行把读功能转移到从服务上因此就可以在单位时间内处理更多的请求从而提升的 Redis 整体的运行速度。而哨兵模式是对于主从功能的升级但当主节点奔溃之后无需人工干预就能自动恢复 Redis 的正常使用。Redis Cluster 是 Redis 3.0 正式推出的Redis 集群是通过将数据库分散存储到多个节点上来平衡各个节点的负载压力。Redis Cluster 采用虚拟哈希槽分区所有的键根据哈希函数映射到 0 ~ 16383 整数槽内计算公式slot CRC16(key) 16383每一个节点负责维护一部分槽以及槽所映射的键值数据。这样 Redis 就可以把读写压力从一台服务器分散给多台服务器了因此性能会有很大的提升。在这三个功能中我们只需要使用一个就行了毫无疑问 Redis Cluster 应该是首选的实现方案它可以把读写压力自动的分担给更多的服务器并且拥有自动容灾的能力。【END】往期推荐Java14发布Switch竟如此简单Lombok也不需要了来用Idea搭建Java14吧阿里巴巴Java开发手册建议设置HashMap的初始容量但设置多少合适呢因为我说volatile 是轻量级的 synchronized面试官让我回去等通知关注下方二维码订阅更多精彩内容朕已阅
http://www.pierceye.com/news/968323/

相关文章:

  • 直接用apk 做登陆网站呢图网站场建设封面
  • 书店网站的建设网络服务器搭建
  • led灯网站模板电商网站开发人员人数
  • 南阳网站建设报价沧州南皮网站建设
  • 网站左侧分类导航菜单用PS做的个人网站图片
  • 返利网 网站开发青岛开发区建网站哪家好
  • 还能电子商务网站建设短网址生成站长工具
  • 有专门做网站的吗网站后台发表文章
  • 秦皇岛汽车网站制作广州网站建设 知名
  • 自己建网站数据怎么做惠州网站制作培训
  • 南山做网站的wordpress自助友链
  • php企业网站源码软件工程师发展前景
  • 如何从建设局网站上更换职称人员哪个网站可以免费做国外网站
  • 情侣博客网站模板下载学校网站建设调查报告
  • 平台网站开发是什么意思全屏的网站
  • 素材图库网站源码网站建设及推广培训班
  • 英国电商网站jsp旅游网站开发系统
  • 机关网站建设引导语开发一个企业网站需要多少钱
  • 徐汇网站推广挣钱最快的小游戏
  • 手机网站开发的目的在线免费看影视网站
  • 湖州网站设计wordpress自动删除p标签
  • 昆明几大网站学生网站建设实训总结
  • 丽江手机网站建设建设公司起名大全
  • seo网站分析工具wordpress的安装包
  • 北京网站建设报价表徐州专业做网站
  • 怎样做网站卖网站国内免费开源crm
  • wordpress多语言网站济宁住房和城乡建设厅网站
  • 免费crm网站下载网站建设 繁体
  • 东莞企业官方网站建设网站建设对产品推销作用大吗
  • php网站路径问题站长工具权重查询