zoukankan      html  css  js  c++  java
  • redis 的优化

    1.pipeling

    “请求-响应”模式的服务器在处理完一个请求后就开始处理下一个请求,不管客户端是否读取到前一个请求的响应结果。这让客户端不需要发一个请求等一个响应的串行,可以一次发送多个请求,再最后一次性读取所有响应。这就叫pipelining(管道化),这种技术几十年来广泛的使用

    使用pipelining时,只需要从客户端一次向Redis发送多条命令(以 )分隔,Redis就会依次执行这些命令,并且把每个命令的返回按顺序组装在一起一次返回

    Pipelining的局限性

    Pipelining只能用于执行连续且无相关性的命令,当某个命令的生成需要依赖于前一个命令的返回时,就无法使用Pipelining了。

    通过Scripting功能,可以规避这一局限性

    2.scripting和事务

    Redis的事务可以确保复数命令执行时的原子性。也就是说Redis能够保证:一个事务中的一组命令是绝对连续执行的,在这些命令执行完成之前,绝对不会有来自于其他连接的其他命令插进去执行。

    通过MULTI和EXEC命令来把这两个命令加入一个事务中:

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set name 1
    QUEUED
    127.0.0.1:6379> get name 
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) "1"
    127.0.0.1:6379> 

    Redis在接收到MULTI命令后便会开启一个事务,这之后的所有读写命令都会保存在队列中但并不执行,直到接收到EXEC命令后,Redis会把队列中的所有命令连续顺序执行,并以数组形式返回每个命令的返回结果。

    可以使用DISCARD命令放弃当前的事务,将保存的命令队列清空。

    需要注意的是,Redis事务不支持回滚
    如果一个事务中的命令出现了语法错误,大部分客户端驱动会返回错误,2.6.5版本以上的Redis也会在执行EXEC时检查队列中的命令是否存在语法错误,如果存在,则会自动放弃事务并返回错误。
    但如果一个事务中的命令有非语法类的错误(比如对String执行HSET操作),无论客户端驱动还是Redis都无法在真正执行这条命令之前发现,所以事务中的所有命令仍然会被依次执行。在这种情况下,会出现一个事务中部分命令成功部分命令失败的情况,然而与RDBMS不同,Redis不提供事务回滚的功能,所以只能通过其他方法进行数据的回滚。

    3 Redis性能调优

    尽管Redis是一个非常快速的内存数据存储媒介,也并不代表Redis不会产生性能问题。
    前文中提到过,Redis采用单线程模型,所有的命令都是由一个线程串行执行的,所以当某个命令执行耗时较长时,会拖慢其后的所有命令,这使得Redis对每个任务的执行效率更加敏感。

    针对Redis的性能优化,主要从下面几个层面入手:

    • 最初的也是最重要的,确保没有让Redis执行耗时长的命令
    • 使用pipelining将连续执行的命令组合执行
    • 操作系统的Transparent huge pages功能必须关闭:
      echo never > /sys/kernel/mm/transparent_hugepage/enabled
    • 如果在虚拟机中运行Redis,可能天然就有虚拟机环境带来的固有延迟。可以通过./redis-cli --intrinsic-latency 100命令查看固有延迟。同时如果对Redis的性能有较高要求的话,应尽可能在物理机上直接部署Redis。
    • 检查数据持久化策略
    • 考虑引入读写分离机制

    3.1  避免长耗时的命令

    • 不要把List当做列表使用,仅当做队列来使用
    • 通过机制严格控制Hash、Set、Sorted Set的大小
    • 可能的话,将排序、并集、交集等操作放在客户端执行
    • 绝对禁止使用KEYS命令
    • 避免一次性遍历集合类型的所有成员,而应使用SCAN类的命令进行分批的,游标式的遍历

    3.2 网络引发的延迟

    • 尽可能使用长连接或连接池,避免频繁创建销毁连接
    • 客户端进行的批量数据操作,应使用Pipeline特性在一次交互中完成。具体请参照本文的Pipelining章节

    3.3 数据持久化引发的延迟 

    • AOF + fsync always的设置虽然能够绝对确保数据安全,但每个操作都会触发一次fsync,会对Redis的性能有比较明显的影响
    • AOF + fsync every second是比较好的折中方案,每秒fsync一次
    • AOF + fsync never会提供AOF持久化方案下的最优性能
    • 使用RDB持久化通常会提供比使用AOF更高的性能,但需要注意RDB的策略配置
    • 每一次RDB快照和AOF Rewrite都需要Redis主进程进行fork操作。fork操作本身可能会产生较高的耗时,与CPU和Redis占用的内存大小有关。根据具体的情况合理配置RDB快照和AOF Rewrite时机,避免过于频繁的fork带来的延迟

    3.4 数据淘汰引发的延迟

    当同一秒内有大量key过期时,也会引发Redis的延迟。在使用时应尽量将key的失效时间错开

    3.5  主从复制与集群分片

    Redis的主从复制能力可以实现一主多从的多节点架构,在这一架构下,主节点接收所有写请求,并将数据同步给多个从节点。
    在这一基础上,我们可以让从节点提供对实时性要求不高的读请求服务,以减小主节点的压力。
    尤其是针对一些使用了长耗时命令的统计类任务,完全可以指定在一个或多个从节点上执行,避免这些长耗时命令影响其他请求的响应

    参考资料:https://www.cnblogs.com/276815076/p/7245333.html

  • 相关阅读:
    Selenium webdriver 操作日历控件
    selenuim-webdriver注解之@FindBy、@FindBys、@FindAll的区别
    配置 mybatis的 log4j.properties
    查询在一个数据库中某个字段存在于哪些表
    Linux下修改Mysql的用户(root)的密码
    MySQL——修改root密码的4种方法(以windows为例)
    报错:1130-host ... is not allowed to connect to this MySql server 开放mysql远程连接 不使用localhost
    C++中的static 成员变量的一些注意点
    #pragma once与#ifndef的区别
    C++类中的成员函数和构造函数为模板函数时的调用方法
  • 原文地址:https://www.cnblogs.com/myvic/p/9316407.html
Copyright © 2011-2022 走看看