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

大连网站网站搭建制作怎么在网上推广广告

大连网站网站搭建制作,怎么在网上推广广告,大墨免费空间申请,建设局一、Redis为什么变慢了 1.Redis真的变慢了吗#xff1f; 对 Redis 进行基准性能测试 例如#xff0c;我的机器配置比较低#xff0c;当延迟为 2ms 时#xff0c;我就认为 Redis 变慢了#xff0c;但是如果你的硬件配置比较高#xff0c;那么在你的运行环境下#xff…一、Redis为什么变慢了 1.Redis真的变慢了吗 对 Redis 进行基准性能测试 例如我的机器配置比较低当延迟为 2ms 时我就认为 Redis 变慢了但是如果你的硬件配置比较高那么在你的运行环境下可能延迟是 0.5ms 时就可以认为 Redis 变慢了。 所以你只有了解了你的 Redis 在生产环境服务器上的基准性能才能进一步评估当其延迟达到什么程度时才认为 Redis 确实变慢了。 为了避免业务服务器到 Redis 服务器之间的网络延迟你需要直接在 Redis 服务器上测试实例的响应延迟情况。执行以下命令就可以测试出这个实例 60 秒内的最大响应延迟 ./redis-cli --intrinsic-latency 120 Max latency so far: 17 microseconds. Max latency so far: 44 microseconds. Max latency so far: 94 microseconds. Max latency so far: 110 microseconds. Max latency so far: 119 microseconds.36481658 total runs (avg latency: 3.2893 microseconds / 3289.32 nanoseconds per run). Worst run took 36x longer than the average latency.从输出结果可以看到这 60 秒内的最大响应延迟为 119 微秒0.119毫秒。你还可以使用以下命令查看一段时间内 Redis 的最小、最大、平均访问延迟。 $ redis-cli -h 127.0.0.1 -p 6379 --latency-history -i 1 min: 0, max: 1, avg: 0.13 (100 samples) -- 1.01 seconds range min: 0, max: 1, avg: 0.12 (99 samples) -- 1.01 seconds range min: 0, max: 1, avg: 0.13 (99 samples) -- 1.01 seconds range min: 0, max: 1, avg: 0.10 (99 samples) -- 1.01 seconds range min: 0, max: 1, avg: 0.13 (98 samples) -- 1.00 seconds range min: 0, max: 1, avg: 0.08 (99 samples) -- 1.01 seconds range如果你观察到的 Redis 运行时延迟是其基线性能的 2 倍及以上就可以认定 Redis 变慢了。 网络对 Redis 性能的影响一个简单的方法是用 iPerf 这样的工具测试网络极限带宽。 服务器端# iperf -s -p 12345 -i 1 -M iperf: option requires an argument -- M ------------------------------------------------------------ Server listening on TCP port 12345 TCP window size: 4.00 MByte (default) ------------------------------------------------------------ [  4] local 172.20.0.113 port 12345 connected with 172.20.0.114 port 56796 [ ID] Interval       Transfer     Bandwidth [  4]  0.0- 1.0 sec   614 MBytes  5.15 Gbits/sec [  4]  1.0- 2.0 sec   622 MBytes  5.21 Gbits/sec [  4]  2.0- 3.0 sec   647 MBytes  5.42 Gbits/sec [  4]  3.0- 4.0 sec   644 MBytes  5.40 Gbits/sec [  4]  4.0- 5.0 sec   651 MBytes  5.46 Gbits/sec [  4]  5.0- 6.0 sec   652 MBytes  5.47 Gbits/sec [  4]  6.0- 7.0 sec   669 MBytes  5.61 Gbits/sec [  4]  7.0- 8.0 sec   670 MBytes  5.62 Gbits/sec [  4]  8.0- 9.0 sec   667 MBytes  5.59 Gbits/sec [  4]  9.0-10.0 sec   667 MBytes  5.60 Gbits/sec [  4]  0.0-10.0 sec  6.35 GBytes  5.45 Gbits/sec 客户端# iperf -c 服务器端IP -p 12345 -i 1 -t 10 -w 20K ------------------------------------------------------------ Client connecting to 172.20.0.113, TCP port 12345 TCP window size: 40.0 KByte (WARNING: requested 20.0 KByte) ------------------------------------------------------------ [  3] local 172.20.0.114 port 56796 connected with 172.20.0.113 port 12345 [ ID] Interval       Transfer     Bandwidth [  3]  0.0- 1.0 sec   614 MBytes  5.15 Gbits/sec [  3]  1.0- 2.0 sec   622 MBytes  5.21 Gbits/sec [  3]  2.0- 3.0 sec   646 MBytes  5.42 Gbits/sec [  3]  3.0- 4.0 sec   644 MBytes  5.40 Gbits/sec [  3]  4.0- 5.0 sec   651 MBytes  5.46 Gbits/sec [  3]  5.0- 6.0 sec   652 MBytes  5.47 Gbits/sec [  3]  6.0- 7.0 sec   669 MBytes  5.61 Gbits/sec [  3]  7.0- 8.0 sec   670 MBytes  5.62 Gbits/sec [  3]  8.0- 9.0 sec   667 MBytes  5.59 Gbits/sec [  3]  9.0-10.0 sec   668 MBytes  5.60 Gbits/sec [  3]  0.0-10.0 sec  6.35 GBytes  5.45 Gbits/sec2.使用复杂度过高的命令 首先第一步你需要去查看一下 Redis 的慢日志slowlog。 Redis 提供了慢日志命令的统计功能它记录了有哪些命令在执行时耗时比较久。 查看 Redis 慢日志之前你需要设置慢日志的阈值。例如设置慢日志的阈值为 5 毫秒并且保留最近 500 条慢日志记录 # 命令执行耗时超过 5 毫秒记录慢日志 CONFIG SET slowlog-log-slower-than 5000 # 只保留最近 500 条慢日志 CONFIG SET slowlog-max-len 5001经常使用 O(N) 以上复杂度的命令例如 SORT、SUNION、ZUNIONSTORE 聚合类命令。 2使用 O(N) 复杂度的命令但 N 的值非常大。 第一种情况导致变慢的原因在于Redis 在操作内存数据时时间复杂度过高要花费更多的 CPU 资源。 第二种情况导致变慢的原因在于Redis 一次需要返回给客户端的数据过多更多时间花费在数据协议的组装和网络传输过程中。 另外我们还可以从资源使用率层面来分析如果你的应用程序操作 Redis 的 OPS 不是很大但 Redis 实例的 CPU 使用率却很高 那么很有可能是使用了复杂度过高的命令导致的。 3.操作bigkey 如果你查询慢日志发现并不是复杂度过高的命令导致的而都是 SET / DEL 这种简单命令出现在慢日志中那么你就要怀疑你的实例否写入了 bigkey。 redis-cli -h 127.0.0.1 -p 6379 --bigkeys -i 1 -------- summary ------- Sampled 829675 keys in the keyspace! Total key length in bytes is 10059825 (avg len 12.13) Biggest string found key:291880 has 10 bytes Biggest   list found mylist:004 has 40 items Biggest    set found myset:2386 has 38 members Biggest   hash found myhash:3574 has 37 fields Biggest   zset found myzset:2704 has 42 members 36313 strings with 363130 bytes (04.38% of keys, avg size 10.00) 787393 lists with 896540 items (94.90% of keys, avg size 1.14) 1994 sets with 40052 members (00.24% of keys, avg size 20.09) 1990 hashs with 39632 fields (00.24% of keys, avg size 19.92) 1985 zsets with 39750 members (00.24% of keys, avg size 20.03)这里我需要提醒你的是当执行这个命令时要注意 2 个问题 1对线上实例进行 bigkey 扫描时Redis 的 OPS 会突增为了降低扫描过程中对 Redis 的影响最好控制一下扫描的频率指定 -i 参数即可它表示扫描过程中每次扫描后休息的时间间隔单位是秒。 2扫描结果中对于容器类型List、Hash、Set、ZSet的 key只能扫描出元素最多的 key。但一个 key 的元素多不一定表示占用内存也多你还需要根据业务情况进一步评估内存占用情况。 4.集中过期 如果你发现平时在操作 Redis 时并没有延迟很大的情况发生但在某个时间点突然出现一波延时其现象表现为变慢的时间点很有规律例如某个整点或者每间隔多久就会发生一波延迟。 如果是出现这种情况那么你需要排查一下业务代码中是否存在设置大量 key 集中过期的情况。 如果有大量的 key 在某个固定时间点集中过期在这个时间点访问 Redis 时就有可能导致延时变大。 Redis 的过期数据采用被动过期 主动过期两种策略 1被动过期只有当访问某个 key 时才判断这个 key 是否已过期如果已过期则从实例中删除。 2主动过期Redis 内部维护了一个定时任务默认每隔 100 毫秒1秒10次就会从全局的过期哈希表中随机取出 20 个 key然后删除其中过期的 key如果过期 key 的比例超过了 25%则继续重复此过程直到过期 key 的比例下降到 25% 以下或者这次任务的执行耗时超过了 25 毫秒才会退出循环。 注意这个主动过期 key 的定时任务是在 Redis 主线程中执行的。 也就是说如果在执行主动过期的过程中出现了需要大量删除过期 key 的情况那么此时应用程序在访问 Redis 时必须要等待这个过期任务执行结束Redis 才可以服务这个客户端请求。 如果此时需要过期删除的是一个 bigkey那么这个耗时会更久。而且这个操作延迟的命令并不会记录在慢日志中。 因为慢日志中只记录一个命令真正操作内存数据的耗时 而 Redis 主动删除过期 key 的逻辑是在命令真正执行之前执行的。 5.实例内存达到上限 当我们把 Redis 当做纯缓存使用时通常会给这个实例设置一个内存上限 maxmemory然后设置一个数据淘汰策略。 当 Redis 内存达到 maxmemory 后每次写入新的数据之前Redis 必须先从实例中踢出一部分数据让整个实例的内存维持在 maxmemory 之下 然后才能把新数据写进来。 这个踢出旧数据的逻辑也是需要消耗时间的而具体耗时的长短要取决于你配置的淘汰策略 allkeys-lru不管 key 是否设置了过期淘汰最近最少访问的 key volatile-lru只淘汰最近最少访问、并设置了过期时间的 key allkeys-random不管 key 是否设置了过期随机淘汰 key volatile-random只随机淘汰设置了过期时间的 key allkeys-ttl不管 key 是否设置了过期淘汰即将过期的 key noeviction不淘汰任何 key实例内存达到 maxmeory 后再写入新数据直接返回错误 allkeys-lfu不管 key 是否设置了过期淘汰访问频率最低的 key4.0版本支持 volatile-lfu只淘汰访问频率最低、并设置了过期时间 key4.0版本支持 一般最常使用的是 allkeys-lru / volatile-lru 淘汰策略 它们的处理逻辑是每次从实例中随机取出一批 key这个数量可配置然后淘汰一个最少访问的 key之后把剩下的 key 暂存到一个池子中继续随机取一批 key并与之前池子中的 key 比较再淘汰一个最少访问的 key。以此往复直到实例内存降到 maxmemory 之下。 需要注意的是Redis 的淘汰数据的逻辑与删除过期 key 的一样也是在命令真正执行之前执行的也就是说它也会增加我们操作 Redis 的延迟而且写 OPS 越高延迟也会越明显。 如果此时你的 Redis 实例中还存储了 bigkey那么在淘汰删除 bigkey 释放内存时 也会耗时比较久。 6.fork耗时严重 当 Redis 开启了后台 RDB 和 AOF rewrite 后在执行时它们都需要主进程创建出一个子进程进行数据的持久化。 主进程创建子进程会调用操作系统提供的 fork 函数。 而 fork 在执行过程中主进程需要拷贝自己的内存页表给子进程 如果这个实例很大那么这个拷贝的过程也会比较耗时。 而且这个 fork 过程会消耗大量的 CPU 资源在完成 fork 之前整个 Redis 实例会被阻塞住无法处理任何客户端请求。 如果此时你的 CPU 资源本来就很紧张那么 fork 的耗时会更长甚至达到秒级这会严重影响 Redis 的性能。 那如何确认确实是因为 fork 耗时导致的 Redis 延迟变大呢 你可以在 Redis 上执行 INFO 命令查看 latest_fork_usec 项单位微秒。 # 上一次 fork 耗时单位微秒 latest_fork_usec:59477这个时间就是主进程在 fork 子进程期间整个实例阻塞无法处理客户端请求的时间。 如果你发现这个耗时很久就要警惕起来了这意味在这期间你的整个 Redis 实例都处于不可用的状态。 除了数据持久化会生成 RDB 之外当主从节点第一次建立数据同步时主节点也创建子进程生成 RDB然后发给从节点进行一次全量同步所以这个过程也会对 Redis 产生性能影响。 7.开启内存大页 除了上面讲到的子进程 RDB 和 AOF rewrite 期间fork 耗时导致的延时变大之外这里还有一个方面也会导致性能问题这就是操作系统是否开启了内存大页机制 。 什么是内存大页 我们都知道应用程序向操作系统申请内存时是按内存页 进行申请的而常规的内存页大小是 4KB。 Linux 内核从 2.6.38 开始支持了内存大页机制 该机制允许应用程序以 2MB 大小为单位向操作系统申请内存。 应用程序每次向操作系统申请的内存单位变大了但这也意味着申请内存的耗时变长。 这对 Redis 会有什么影响呢 当 Redis 在执行后台 RDB采用 fork 子进程的方式来处理。但主进程 fork 子进程后此时的主进程依旧是可以接收写请求 的而进来的写请求会采用 Copy On Write写时复制的方式操作内存数据。 也就是说主进程一旦有数据需要修改Redis 并不会直接修改现有内存中的数据而是先将这块内存数据拷贝出来再修改这块新内存的数据 这就是所谓的「写时复制」。 写时复制你也可以理解成谁需要发生写操作谁就需要先拷贝再修改。 这样做的好处是父进程有任何写操作并不会影响子进程的数据持久化子进程只持久化 fork 这一瞬间整个实例中的所有数据即可不关心新的数据变更因为子进程只需要一份内存快照然后持久化到磁盘上。 但是请注意主进程在拷贝内存数据时这个阶段就涉及到新内存的申请如果此时操作系统开启了内存大页那么在此期间客户端即便只修改 10B 的数据Redis 在申请内存时也会以 2MB 为单位向操作系统申请申请内存的耗时变长进而导致每个写请求的延迟增加影响到 Redis 性能。 同样地如果这个写请求操作的是一个 bigkey那主进程在拷贝这个 bigkey 内存块时一次申请的内存会更大时间也会更久。可见bigkey 在这里又一次影响到了性能。 8.开启AOF 前面我们分析了 RDB 和 AOF rewrite 对 Redis 性能的影响主要关注点在 fork 上。 其实关于数据持久化方面还有影响 Redis 性能的因素这次我们重点来看 AOF 数据持久化。 如果你的 AOF 配置不合理还是有可能会导致性能问题。 当 Redis 开启 AOF 后其工作原理如下 1Redis 执行写命令后把这个命令写入到 AOF 文件内存中write 系统调用 2Redis 根据配置的 AOF 刷盘策略把 AOF 内存数据刷到磁盘上fsync 系统调用 为了保证 AOF 文件数据的安全性Redis 提供了 3 种刷盘机制 1appendfsync always主线程每次执行写操作后立即刷盘此方案会占用比较大的磁盘 IO 资源但数据安全性最高。 2appendfsync no主线程每次写操作只写内存就返回内存数据什么时候刷到磁盘交由操作系统决定此方案对性能影响最小但数据安全性也最低Redis 宕机时丢失的数据取决于操作系统刷盘时机。 3appendfsync everysec主线程每次写操作只写内存就返回然后由后台线程每隔 1 秒执行一次刷盘操作触发fsync系统调用此方案对性能影响相对较小但当 Redis 宕机时会丢失 1 秒的数据。 看到这里我猜你肯定和大多数人的想法一样选比较折中的方案 appendfsync everysec 就没问题了吧 这个方案优势在于Redis 主线程写完内存后就返回具体的刷盘操作是放到后台线程中执行的后台线程每隔 1 秒把内存中的数据刷到磁盘中。 这种方案既兼顾了性能又尽可能地保证了数据安全是不是觉得很完美 但是这里我要给你泼一盆冷水了采用这种方案你也要警惕一下因为这种方案还是存在导致 Redis 延迟变大的情况发生甚至会阻塞整个 Redis。 你试想这样一种情况当 Redis 后台线程在执行 AOF 文件刷盘时如果此时磁盘的 IO 负载很高那这个后台线程在执行刷盘操作fsync系统调用时就会被阻塞住。 此时的主线程依旧会接收写请求紧接着主线程又需要把数据写到文件内存中write 系统调用当主线程使用后台子线程执行了一次 fsync需要再次把新接收的操作记录写回磁盘时如果主线程发现上一次的 fsync 还没有执行完那么它就会阻塞。 所以如果后台子线程执行的 fsync 频繁阻塞的话比如 AOF 重写占用了大量的磁盘 IO 带宽主线程也会阻塞导致 Redis 性能变慢。 看到了么在这个过程中主线程依旧有阻塞的风险。 所以尽管你的 AOF 配置为 appendfsync everysec也不能掉以轻心要警惕磁盘压力过大导致的 Redis 有性能问题。 那什么情况下会导致磁盘 IO 负载过大以及如何解决这个问题呢 我总结了以下几种情况你可以参考进行问题排查 1进程正在执行 AOF rewrite这个过程会占用大量的磁盘 IO 资源 2有其他应用程序在执行大量的写文件操作也会占用磁盘 IO 资源 对于情况1说白了就是Redis 的 AOF 后台子线程刷盘操作撞上了子进程 AOF rewrite 9.绑定CPU 很多时候我们在部署服务时为了提高服务性能降低应用程序在多个 CPU 核心之间的上下文切换带来的性能损耗通常采用的方案是进程绑定 CPU 的方式提高性能。 我们都知道一般现代的服务器会有多个 CPU而每个 CPU 又包含多个物理核心每个物理核心又分为多个逻辑核心每个物理核下的逻辑核共用 L1/L2 Cache。 而 Redis Server 除了主线程服务客户端请求之外还会创建子进程、子线程。 其中子进程用于数据持久化而子线程用于执行一些比较耗时操作例如异步释放 fd、异步 AOF 刷盘、异步 lazy-free 等等。 如果你把 Redis 进程只绑定了一个 CPU 逻辑核心上那么当 Redis 在进行数据持久化时fork 出的子进程会继承父进程的 CPU 使用偏好。 而此时的子进程会消耗大量的 CPU 资源进行数据持久化把实例数据全部扫描出来需要耗费CPU这就会导致子进程会与主进程发生 CPU 争抢进而影响到主进程服务客户端请求访问延迟变大。 这就是 Redis 绑定 CPU 带来的性能问题。 10.使用Swap 如果你发现 Redis 突然变得非常慢每次的操作耗时都达到了几百毫秒甚至秒级那此时你就需要检查 Redis 是否使用到了 Swap在这种情况下 Redis 基本上已经无法提供高性能的服务了。 什么是 Swap为什么使用 Swap 会导致 Redis 的性能下降 如果你对操作系统有些了解就会知道操作系统为了缓解内存不足对应用程序的影响允许把一部分内存中的数据换到磁盘上以达到应用程序对内存使用的缓冲这些内存数据被换到磁盘上的区域就是 Swap。 问题就在于当内存中的数据被换到磁盘上后Redis 再访问这些数据时就需要从磁盘上读取访问磁盘的速度要比访问内存慢几百倍 尤其是针对 Redis 这种对性能要求极高、性能极其敏感的数据库来说这个操作延时是无法接受的。 此时你需要检查 Redis 机器的内存使用情况确认是否存在使用了 Swap。 你可以通过以下方式来查看 Redis 进程是否使用到了 Swap # 先找到 Redis 的进程 ID $ ps -aux | grep redis-server # 查看 Redis Swap 使用情况 $ cat /proc/$pid/smaps | egrep ^(Swap|Size)输出结果如下 Size:               1256 kB Swap:                  0 kB Size:                  4 kB Swap:                  0 kB Size:                132 kB Swap:                  0 kB Size:              63488 kB Swap:                  0 kB Size:                132 kB Swap:                  0 kB Size:              65404 kB Swap:                  0 kB Size:            1921024 kB Swap:                  0 kB每一行 Size 表示 Redis 所用的一块内存大小Size 下面的 Swap 就表示这块 Size 大小的内存有多少数据已经被换到磁盘上了如果这两个值相等说明这块内存的数据都已经完全被换到磁盘上了。 如果只是少量数据被换到磁盘上例如每一块 Swap 占对应 Size 的比例很小那影响并不是很大。如果是几百兆甚至上 GB 的内存 被换到了磁盘上那么你就需要警惕了这种情况 Redis 的性能肯定会急剧下降。 11.碎片整理 Redis 的数据都存储在内存中当我们的应用程序频繁修改 Redis 中的数据时就有可能会导致 Redis 产生内存碎片。 内存碎片会降低 Redis 的内存使用率我们可以通过执行 INFO 命令得到这个实例的内存碎片率 # Memory used_memory:5709194824 used_memory_human:5.32G used_memory_rss:8264855552 used_memory_rss_human:7.70G ... mem_fragmentation_ratio:1.45这个内存碎片率是怎么计算的 很简单mem_fragmentation_ratio used_memory_rss / used_memory。 其中 used_memory 表示 Redis 存储数据的内存大小而 used_memory_rss 表示操作系统实际分配给 Redis 进程的大小。 如果 mem_fragmentation_ratio 1.5说明内存碎片率已经超过了 50%这时我们就需要采取一些措施来降低内存碎片了。 解决的方案一般如下 1如果你使用的是 Redis 4.0 以下版本只能通过重启实例来解决 2如果你使用的是 Redis 4.0 版本它正好提供了自动碎片整理的功能可以通过配置开启碎片自动整理。 但是开启内存碎片整理它也有可能会导致 Redis 性能下降。 原因在于Redis 的碎片整理工作是也在主线程 中执行的当其进行碎片整理时必然会消耗 CPU 资源产生更多的耗时从而影响到客户端的请求。 所以当你需要开启这个功能时最好提前测试评估它对 Redis 的影响。 Redis 碎片整理的参数配置如下 # 开启自动内存碎片整理总开关 activedefrag yes# 内存使用 100MB 以下不进行碎片整理 active-defrag-ignore-bytes 100mb# 内存碎片率超过 10%开始碎片整理 active-defrag-threshold-lower 10 # 内存碎片率超过 100%尽最大努力碎片整理 active-defrag-threshold-upper 100# 内存碎片整理占用 CPU 资源最小百分比 active-defrag-cycle-min 1 # 内存碎片整理占用 CPU 资源最大百分比 active-defrag-cycle-max 25# 碎片整理期间对于 List/Set/Hash/ZSet 类型元素一次 Scan 的数量 active-defrag-max-scan-fields 1000二、Redis如何优化 1.慢查询优化 1尽量不使用 O(N) 以上复杂度过高的命令对于数据的聚合操作放在客户端做。 2执行 O(N) 命令保证 N 尽量的小推荐 N 300每次获取尽量少的数据让 Redis 可以及时处理返回。 2.集中过期优化 一般有两种方案来规避这个问题 1.集中过期 key 增加一个随机过期时间把集中过期的时间打散降低 Redis 清理过期 key 的压力 2.如果你使用的 Redis 是 4.0 以上版本可以开启 lazy-free 机制当删除过期 key 时把释放内存的操作放到后台线程中执行避免阻塞主线程。 第一种方案在设置 key 的过期时间时增加一个随机时间伪代码可以这么写 # 在过期时间点之后的 5 分钟内随机过期掉 redis.expireat(key, expire_time  random(300))第二种方案Redis 4.0 以上版本开启 lazy-free 机制 # 释放过期 key 的内存放到后台线程执行 lazyfree-lazy-expire yes运维层面你需要把 Redis 的各项运行状态数据监控起来在 Redis 上执行 INFO 命令就可以拿到这个实例所有的运行状态数据。 在这里我们需要重点关注 expired_keys 这一项 它代表整个实例到目前为止累计删除过期 key 的数量。 你需要把这个指标监控起来当这个指标在很短时间内出现了突增需要及时报警出来然后与业务应用报慢的时间点进行对比分析确认时间是否一致如果一致则可以确认确实是因为集中过期 key 导致的延迟变大。 3.实例内存达到上限优化 1避免存储 bigkey降低释放内存的耗时 2淘汰策略改为随机淘汰随机淘汰比 LRU 要快很多视业务情况调整 3拆分实例把淘汰 key 的压力分摊到多个实例上 4如果使用的是 Redis 4.0 以上版本开启 layz-free 机制把淘汰 key 释放内存的操作放到后台线程中执行配置 lazyfree-lazy-eviction yes 4.fork耗时严重优化 1控制 Redis 实例的内存尽量在 10G 以下执行 fork 的耗时与实例大小有关实例越大耗时越久。 2合理配置数据持久化策略在 slave 节点执行 RDB 备份推荐在低峰期执行而对于丢失数据不敏感的业务例如把 Redis 当做纯缓存使用可以关闭 AOF 和 AOF rewrite。 3Redis 实例不要部署在虚拟机上fork 的耗时也与系统也有关虚拟机比物理机耗时更久。 4降低主从库全量同步的概率适当调大 repl-backlog-size 参数避免主从全量同步。 从建立同步时优先检测是否可以尝试只同步部分数据这种情况就是针对于之前已经建立好了复制链路只是因为故障导致临时断开故障恢复后重新建立同步时为了避免全量同步的资源消耗Redis会优先尝试部分数据同步如果条件不符合才会触发全量同步。 这个判断依据就是在master上维护的复制缓冲区大小如果这个缓冲区配置的过小很有可能在主从断开复制的这段时间内master产生的写入导致复制缓冲区的数据被覆盖重新建立同步时的slave需要同步的offset位置在master的缓冲区中找不到那么此时就会触发全量同步。 如何避免这种情况解决方案就是适当调大复制缓冲区repl-backlog-size的大小这个缓冲区的大小默认为1MB如果实例写入量比较大可以针对性调大此配置。 5.多核CPU优化 那如何解决这个问题呢 如果你确实想要绑定 CPU可以优化的方案是不要让 Redis 进程只绑定在一个 CPU 逻辑核上而是绑定在多个逻辑核心上而且绑定的多个逻辑核心最好是同一个物理核心这样它们还可以共用 L1/L2 Cache。 当然即便我们把 Redis 绑定在多个逻辑核心上也只能在一定程度上缓解主线程、子进程、后台线程在 CPU 资源上的竞争。 因为这些子进程、子线程还是会在这多个逻辑核心上进行切换存在性能损耗。 如何再进一步优化 可能你已经想到了我们是否可以让主线程、子进程、后台线程分别绑定在固定的 CPU 核心上不让它们来回切换这样一来他们各自使用的 CPU 资源互不影响。 其实这个方案 Redis 官方已经想到了。 Redis 在 6.0 版本已经推出了这个功能我们可以通过以下配置对主线程、后台线程、后台 RDB 进程、AOF rewrite 进程绑定固定的 CPU 逻辑核心 Redis6.0 前绑定CPU核 taskset -c 0 ./redis-serverRedis6.0 后绑定CPU核 # Redis Server 和 IO 线程绑定到 CPU核心 0,2,4,6 server_cpulist 0-7:2 # 后台子线程绑定到 CPU核心 1,3 bio_cpulist 1,3 # 后台 AOF rewrite 进程绑定到 CPU 核心 8,9,10,11 aof_rewrite_cpulist 8-11 # 后台 RDB 进程绑定到 CPU 核心 1,10,11 # bgsave_cpulist 1,10-1如果你使用的正好是 Redis 6.0 版本就可以通过以上配置来进一步提高 Redis 性能。 这里我需要提醒你的是一般来说Redis 的性能已经足够优秀除非你对 Redis 的性能有更加严苛的要求否则不建议你绑定 CPU。 6.查看Redis内存是否发生Swap $ redis-cli info | grep process_id process_id: 5332然后进入 Redis 所在机器的 /proc 目录下的该进程目录中 $ cd /proc/5332最后运行下面的命令查看该 Redis 进程的使用情况。在这儿我只截取了部分结果 $cat smaps | egrep ^(Swap|Size) Size: 584 kB Swap: 0 kB Size: 4 kB Swap: 4 kB Size: 4 kB Swap: 0 kB Size: 462044 kB Swap: 462008 kB Size: 21392 kB Swap: 0 kB一旦发生内存 swap最直接的解决方法就是增加机器内存。如果该实例在一个 Redis 切片集群中可以增加 Redis 集群的实例个数来分摊每个实例服务的数据量进而减少每个实例所需的内存量。 7.内存大页 如果采用了内存大页那么即使客户端请求只修改 100B 的数据Redis 也需要拷贝 2MB 的大页。相反如果是常规内存页机制只用拷贝 4KB。两者相比你可以看到当客户端请求修改或新写入数据较多时内存大页机制将导致大量的拷贝这就会影响 Redis 正常的访存操作最终导致性能变慢。 首先我们要先排查下内存大页。方法是在 Redis 实例运行的机器上执行如下命令: $ cat /sys/kernel/mm/transparent_hugepage/enabled [always] madvise never如果执行结果是 always就表明内存大页机制被启动了如果是 never就表示内存大页机制被禁止。 在实际生产环境中部署时我建议你不要使用内存大页机制 操作也很简单只需要执行下面的命令就可以了 echo never /sys/kernel/mm/transparent_hugepage/enabled其实操作系统提供的内存大页机制其优势是可以在一定程序上降低应用程序申请内存的次数。 但是对于 Redis 这种对性能和延迟极其敏感的数据库来说我们希望 Redis 在每次申请内存时耗时尽量短所以我不建议你在 Redis 机器上开启这个机制。 **8.删除使用Lazy Free ** 支持版本Redis 4.0 1主动删除键使用lazy free UNLINK命令 127.0.0.1:7000 LLEN mylist (integer) 2000000 127.0.0.1:7000 UNLINK mylist (integer) 1 127.0.0.1:7000 SLOWLOG get 1) 1) (integer) 12) (integer) 15054651883) (integer) 304) 1) UNLINK2) mylist5) 127.0.0.1:170156) 注意DEL命令还是并发阻塞的删除操作 FLUSHALL/FLUSHDB ASYNC 127.0.0.1:7000 DBSIZE (integer) 1812295 127.0.0.1:7000 flushall  //同步清理实例数据180万个key耗时1020毫秒 OK (1.02s) 127.0.0.1:7000 DBSIZE (integer) 1812637 127.0.0.1:7000 flushall async  //异步清理实例数据180万个key耗时约9毫秒 OK 127.0.0.1:7000 SLOWLOG get1) 1) (integer) 29961092) (integer) 15054659893) (integer) 9274       //指令运行耗时9.2毫秒4) 1) flushall2) async5) 127.0.0.1:201106) 2被动删除键使用lazy free lazy free应用于被动删除中目前有4种场景每种场景对应一个配置参数默认都是关闭。 lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no slave-lazy-flush nolazyfree-lazy-eviction 针对redis内存使用达到maxmeory并设置有淘汰策略时在被动淘汰键时是否采用lazy free机制因为此场景开启lazy free, 可能使用淘汰键的内存释放不及时导致redis内存超用超过maxmemory的限制。此场景使用时请结合业务测试。生产环境不建议设置yes lazyfree-lazy-expire 针对设置有TTL的键达到过期后被redis清理删除时是否采用lazy free机制此场景建议开启因TTL本身是自适应调整的速度。 lazyfree-lazy-server-del 针对有些指令在处理已存在的键时会带有一个隐式的DEL键的操作。如rename命令当目标键已存在,redis会先删除目标键如果这些目标键是一个big key,那就会引入阻塞删除的性能问题。此参数设置就是解决这类问题建议可开启。 slave-lazy-flush 针对slave进行全量数据同步slave在加载master的RDB文件前会运行flushall来清理自己的数据场景 参数设置决定是否采用异常flush机制。如果内存变动不大建议可开启。可减少全量同步耗时从而减少主库因输出缓冲区爆涨引起的内存使用增长。 3lazy free的监控 lazy free能监控的数据指标只有一个值lazyfree_pending_objects表示redis执行lazy free操作在等待被实际回收内容的键个数。并不能体现单个大键的元素个数或等待lazy free回收的内存大小。所以此值有一定参考值可监测redis lazy free的效率或堆积键数量比如在flushall async场景下会有少量的堆积。 # info memory# Memory lazyfree_pending_objects:0注意事项 unlink命令入口函数unlinkCommand()和del调用相同函数delGenericCommand()进行删除KEY操作使用lazy标识是否为lazyfree调用。如果是lazyfree,则调用dbAsyncDelete()函数。 但并非每次unlink命令就一定启用lazy freeredis会先判断释放KEY的代价(cost),当cost大于LAZYFREE_THRESHOLD64才进行lazy free. 释放key代价计算函数lazyfreeGetFreeEffort()集合类型键且满足对应编码cost就是集合键的元数个数否则cost就是1。 举例 一个包含100元素的list key, 它的free cost就是100 一个512MB的string key, 它的free cost是1 所以可以看出redis的lazy free的cost计算主要时间复杂度相关。 9.AOF优化 Redis 提供了一个配置项当子进程在 AOF rewrite 期间可以让后台子线程不执行刷盘不触发 fsync 系统调用操作。 这相当于在 AOF rewrite 期间临时把 appendfsync 设置为了 none配置如下 # AOF rewrite 期间AOF 后台子线程不进行刷盘操作 # 相当于在这期间临时把 appendfsync 设置为了 none no-appendfsync-on-rewrite yes当然开启这个配置项在 AOF rewrite 期间如果实例发生宕机那么此时会丢失更多的数据性能和数据安全性你需要权衡后进行选择。 如果占用磁盘资源的是其他应用程序那就比较简单了你需要定位到是哪个应用程序在大量写磁盘然后把这个应用程序迁移到其他机器上执行就好了避免对 Redis 产生影响。 当然如果你对 Redis 的性能和数据安全都有很高的要求那么建议从硬件层面来优化 更换为 SSD 磁盘提高磁盘的 IO 能力保证 AOF 期间有充足的磁盘资源可以使用。同时尽可能让Redis运行在独立的机器上。 10.Swap优化 1增加机器的内存让 Redis 有足够的内存可以使用 2整理内存空间释放出足够的内存供 Redis 使用然后释放 Redis 的 Swap让 Redis 重新使用内存 释放 Redis 的 Swap 过程通常要重启实例为了避免重启实例对业务的影响一般会先进行主从切换然后释放旧主节点的 Swap重启旧主节点实例待从库数据同步完成后再进行主从切换即可。 预防的办法就是你需要对 Redis 机器的内存和 Swap 使用情况进行监控在内存不足或使用到 Swap 时报警出来及时处理。 三、Redis变慢了排查步骤 1.获取 Redis 实例在当前环境下的基线性能。 2.是否用了慢查询命令如果是的话就使用其他命令替代慢查询命令或者把聚合计算命令放在客户端做。 3.是否对过期 key 设置了相同的过期时间对于批量删除的 key可以在每个 key 的过期时间上加一个随机数避免同时删除。 4.是否存在 bigkey对于 bigkey 的删除操作如果你的 Redis 是 4.0 及以上的版本可以直接利用异步线程机制减少主线程阻塞如果是 Redis 4.0 以前的版本可以使用 SCAN 命令迭代删除对于 bigkey 的集合查询和聚合操作可以使用 SCAN 命令在客户端完成。 5.Redis AOF 配置级别是什么业务层面是否的确需要这一可靠性级别如果我们需要高性能同时也允许数据丢失可以将配置项 no-appendfsync-on-rewrite 设置为 yes避免 AOF 重写和 fsync 竞争磁盘 IO 资源导致 Redis 延迟增加。当然 如果既需要高性能又需要高可靠性最好使用高速固态盘作为 AOF 日志的写入盘。 6.Redis 实例的内存使用是否过大发生 swap 了吗如果是的话就增加机器内存或者是使用 Redis 集群分摊单机 Redis 的键值对数量和内存压力。同时要避免出现 Redis 和其他内存需求大的应用共享机器的情况。 7.在 Redis 实例的运行环境中是否启用了透明大页机制如果是的话直接关闭内存大页机制就行了。 8.是否运行了 Redis 主从集群如果是的话把主库实例的数据量大小控制在 2~4GB以免主从复制时从库因加载大的 RDB 文件而阻塞。 9.是否使用了多核 CPU 或 NUMA 架构的机器运行 Redis 实例使用多核 CPU 时可以给 Redis 实例绑定物理核使用 NUMA 架构时注意把 Redis 实例和网络中断处理程序运行在同一个 CPU Socket 上。
http://www.tj-hxxt.cn/news/225255.html

相关文章:

  • 做招聘信息的网站有哪些内容上传网站程序
  • 网站制作 万网用户界面设计的重要性
  • 电商网站设计页面设计电商运营八大流程
  • 用来备案企业网站wordpress与微信支付宝
  • 现在建网站可以赚钱吗掌握商务网站建设内容
  • 2019建设什么网站好运营北风淘淘网站开发
  • 钦州市建设工程质量监督站网站哈尔滨市建设工程交易中心
  • 韩国的电商网站哈尔滨网站优化方式
  • 海南网站公司几十万做网站平台
  • 域名和网站的关系住房和城乡建设厅安全员证
  • 2018年网站开发语言排行拼团做的比较好的网站
  • 建设境外网站需要什么手续潍坊网站建设 中公
  • 网站优化百度seo兼职优化
  • 国外社交网站做的比较好的是建设网站的企业邮箱网站建设服务
  • 网站建设步骤流程详细介绍中山好的网站建设
  • 潍坊知名网站建设怎么收费集团官网及站群网站建设
  • 国网公司网站如何让网站gzip
  • 国内f型网页布局的网站宁波 做网站
  • wordpress装多站点wordpress调用指定文章分类链接
  • 如何建设一家网站学做ps的软件的网站有哪些
  • vr技术在网站建设的应用免费制作短视频的软件
  • 做电子相册的大网站企业网站cms
  • 自己电脑上做的网站 怎么让别人看宁波定制网站建设解决方案
  • 0元购怎么在网站做小微企业管理软件
  • 网站需求清单wordpress中文网站模板下载
  • 乐清网站建设哪家好寿光哪里做网站
  • 建网站买的是什么微信扫一扫登录网站如何做
  • 做网站淮南宝塔本地wordpress
  • 哪几个网站做acm题目比较好厦门网站建设哪家强
  • 网站备案 关闭网站免费seo快速排名工具