zoukankan      html  css  js  c++  java
  • redis 初探

    防止链接超时:conn = redis.Redis(host=self.settings['REDIS_HOST'], port=self.settings['REDIS_PORT'], health_check_interval=30)

    下载地址:https://github.com/ServiceStack/redis-windows,安装实例:https://www.cnblogs.com/kendrick/p/6806079.html

    redis命令参考:http://doc.redisfans.com/

    python 操作redis官网:https://www.cnblogs.com/pingqiang/p/7892906.html#_label5_1    https://cloud.tencent.com/developer/article/1151834    https://redis-py.readthedocs.io/en/latest/

    微软维护的版本:https://github.com/MicrosoftArchive/redis/releases

    redis命令:http://blog.scmud.com/?p=184  python操作redis http://blog.scmud.com/?p=190  ,

    参考资料:https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247484609&idx=1&sn=4c053236699fde3c2db1241ab497487b&chksm=ebd745c0dca0ccd682e91938fc30fa947df1385b06d6ae9bb52514967b0736c66684db2f1ac9&token=177635168&lang=zh_CN#rd

    中文网:http://www.redis.cn/

    找拖慢redis的命令 :INFO commandstats
    命令执行了多少次,执行命令所耗费的毫秒数(每个命令的总时间和平均时间)
    只需要简单地执行 CONFIG RESETSTAT 命令就可以重置,这样你就可以得到一个全新的统计结果。

      • 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
      • Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
      • string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象
      • 一个client可以通过一个socket连接发起多个请求命令。每个请求命令发出后client通常会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client
        利用pipeline的方式从client打包多条命令一起发出,不需要等待单条命令的响应返回,而redis服务端会处理完多条命令后会将多条命令的处理结果打包到一起返回给客户端。

      • redis各个数据结构的应用举例
           1.1 String类型应用举例:
             利用INCR,DECR命令来构建计数器系统。
           1.2List类型应用举例
             利用list的栈特性实现取最新n条数据的功能
             利用list的队列特性实现简单消息队列
           1.3Set类型应用举例
             去重操作
           1.4Sorted Set类型应用举例
             将排序值作为score来实现排行榜应用
             将优先级作为scores来实现优先级队列
           1.5Hash类型应用举例
             将你的model或者传统数据库数据映射成Hash

        Redis由C语言编写

        Redis的存储是以key-value的形式的。Redis中的key一定是字符串,value可以是string、list、hash、set、sortset这几种常用的

      • 设置键的生存时间可以通过EXPIRE或者PEXPIRE命令。
        设置键的过期时间可以通过EXPIREAT或者PEXPIREAT命令。

        查看剩余生存时间的命令:
        PERSIST(移除过期时间)
        TTL(Time To Live)返回剩余生存时间,以秒为单位
        PTTL以毫秒为单位返回键的剩余生存时间

      • ================
      • Redis采用的是惰性删除+定期删除两种策略,所以说,在Redis里边如果过期键到了过期的时间了,未必被立马删除的!
        • 惰性删除(对CPU极度友好,对内存极度不友好)

          • 每次从键空间取键的时候,判断一下该键是否过期了,如果过期了就删除。

        • 定期删除(折中)

          • 每隔一段时间去删除过期键,限制删除的执行时长和频率

     ========================

    当内存使用量超出时,会施行数据淘汰策略

    Redis提供了两种不同的持久化方法来讲数据存储到硬盘里边:

    • RDB(基于快照),将某一时刻的所有数据保存到一个RDB文件中。

    • AOF(append-only-file),当Redis服务器执行写命令的时候,将执行的写命令保存到AOF文件中

    • AOF是通过保存Redis服务器所执行的写命令来记录数据库的数据的

    ==========================

    Redis有5种数据类型:

    • string,最基本的数据类型,也是其他四种数据类型的基础,能存储任何形式的字符创。适用:存储信息对象序列化JSON格式。get/set操作
    • hash,哈希类型是一个字符串类型的字段和字段值的映射表,将一个对象存成hash类型占用更少的内存,并且可以更方便的存取整个对象。适用:经常被并发请求的小数据查询,如:最近五日的超高返商品数据,存储在Hash中,field=商品ID,value=商品信息(对象序列化JSON格式)。hmset/hgetall操作。
    • list,链表类型可以存储一个有序的字符串列表,用链表类型的LPUSH和LPOP或者RPUSH和RPOP实现栈的功能,用LPUSH和RPOP或者RPUSH和LPOP实现队列的功能。适用:作为信息队列使用,不断的Lpush数据到List中,rpop数据出来入库,或者处理。列表的最大长度为 232 - 1 个元素(4294967295,每个列表的元素超过四十亿)。lpush list_name list_element/ lrange list_name start_index end_index
    • set,集合类型。集合元素是唯一的,无序的。集合间可以进行交并差操作。sadd/smembers
    • zset,有序集合类型,在set的基础上多了一个有序。适用:搜索关键字排名。zadd/zrangebyscore

    Redis优点

    • 异常快速 : Redis是非常快的,每秒可以执行大约110000设置操作,81000个/每秒的读取操作。
    • 支持丰富的数据类型 : Redis支持最大多数开发人员已经知道如列表,集合,可排序集合,哈希等数据类型。这使得在应用中很容易解决的各种问题,因为我们知道哪些问题处理使用哪种数据类型更好解决。
    • 支持pub/sub消息订阅机制,可以用来进行消息订阅与通知。
    • 支持持久化操作,可以进行aof及rdb数据持久化到磁盘,从而进行数据备份或数据恢复等操作,较好的防止数据丢失的手段。 
      *操作都是原子的 : 所有 Redis 的操作都是原子,从而确保当两个客户同时访问 Redis 服务器得到的是更新后的值(最新值)。

    Redis缺点

      • Redis只能使用单线程,性能受限于CPU性能,故单实例CPU最高才可能达到5-6wQPS每秒
      • Redis在string类型上会消耗较多内存,可以使用dict(hash表)压缩存储以降低内存耗用

    =========================

    Redis的键命名建议按照"object-type:id:field(表:主键:列)"的方式 

    Set login:1:login_times 5
    Set login:2:login_times 1
    Set login:3:login_times 2
    
    Set login:1:last_login_time 2011-1-1
    Set login:2:last_login_time 2011-2-1
    Set login:3:last_login_time 2011-3-1

    =========================

    最佳实践: 
    1、取代将数据存储为数千(或者数百万)独立的字符串,可以考虑使用哈希数据结构将相关数据进行分组。哈希表是非常有效率的,并且可以减少你的内存使用

    2、合适时候,使用list代替set。如果你不需要使用set特性,List在使用更少内存的情况下可以提供比set更快的速度。Sorted sets是最昂贵的数据结构,不管是内存消耗还是基本操作的复杂性

    3、Redis中一个经常被忽视的功能就是bitmaps或者bitsets(V2.2之后)。Bitsets允许你在Redis值上执行多个bit-level操作,比如一些轻量级的分析

    =========================Redis配置文件redis.conf

    中文redis官网参数介绍:https://www.redis.net.cn/tutorial/3504.html

    配置 作用 默认
    bind

    当配置了bind之后:

    • 只有bind指定的ip可以直接访问Redis,这样可以避免将Redis服务暴露于危险的网络环境中,防止一些不安全的人随随便便通过远程访问Redis
    • 如果bind选项为空或0.0.0.0的话,那会接受所有来自于可用网络接口的连接
    127.0.0.1
    protected-mode

    protected-mode是Redis3.2之后的新特性,用于加强Redis的安全管理,当满足以下两种情况时,protected-mode起作用:

    • bind未设置,即接收所有来自网络的连接
    • 密码未设置

    当满足以上两种情况且protected-mode=yes的时候,访问Redis将报错,即密码未设置的情况下,无密码访问Redis只能通过安装Redis的本机进行访问

    yes
    port Redis访问端口,由于Redis是单线程模型,因此单机开多个Redis进程的时候会修改端口,不然一般使用大家比较熟悉的6379端口就可以了 6379
    tcp-backlog 半连接队列的大小,对半连接队列不熟的可以看我以前的文章TCP:三次握手、四次握手、backlog及其他 511
    timeout 指定在一个client空闲多少秒之后就关闭它,0表示不管 0
    tcp-keepalive

    设置tcp协议的keepalive,从Redis的注释来看,这个参数有两个作用:

    • 发现死的连接
    • 从中间网络设备的角度看连接是否存活
    300
    daemonize 这个前面说过了,指定Redis是否以守护进程的方式启动 no
    supervised 这个参数表示可以通过upstart和systemd管理Redis守护进程,这个具体和操作系统相关,资料也不是很多,就暂时不管了 no
    pidfile 当Redis以守护进程的方式运行的时候,Redis默认会把pid写到pidfile指定的文件中 /var/run/redis_6379.pid
    loglevel

    指定Redis的日志级别,Redis本身的日志级别有notice、verbose、notice、warning四种,按照文档的说法,这四种日志级别的区别是:

    • debug,非常多信息,适合开发/测试
    • verbose,很多很少有用的信息(直译,读着拗口,从上下文理解应该是有用信息不多的意思),但并不像debug级别这么混乱
    • notice,适度的verbose级别的输出,很可能是生产环境中想要的
    • warning,只记录非常重要/致命的信息
    notice
    logfile 配置log文件地址,默认打印在命令行终端的窗口上 ""
    databases 设置Redis数据库的数量,默认使用0号DB 16
     save 把Redis数据保存到磁盘上,这个是在RDB的时候用的,介绍RDB的时候专门说这个 

    save 900 1

    save 300 10

    save 60 10000 

     stop-writes-on-bgsave-error

    当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。

    这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。

    如果Redis重启了,那么又可以重新开始接收数据了

     yes
    rdbcompression  是否在RBD的时候使用LZF压缩字符串,如果希望省点CPU,那就设为no,不过no的话数据集可能就比较大  yes 
     rdbchecksum 是否校验RDB文件,在RDB文件中有一个checksum专门用于校验 yes 
     dbfilename dump的文件位置 dump.rdb 
     dir Redis工作目录 ./ 
     slaveof 主从复制,使用slaveof让一个节点称为某个节点的副本,这个只需要在副本上配置  关闭
    masterauth 如果主机使用了requirepass配置进行密码保护,使用这个配置告诉副本连接的时候需要鉴权 关闭
    slave-serve-stale-data

    当一个Slave与Master失去联系或者复制正在进行中,Slave可能会有两种表现:

    • 如果为yes,Slave仍然会应答客户端请求,但返回的数据可能是过时的或者数据可能是空的
    • 如果为no,在执行除了INFO、SLAVEOF两个命令之外,都会应答"SYNC with master in progres"错误
    yes
     slave-read-only 配置Redis的Slave实例是否接受写操作,即Slave是否为只读Redis  yes
     slave-priority 从站优先级是可以从redis的INFO命令输出中查到的一个整数。当主站不能正常工作时,redis sentinel使用它来选择一个从站并将它提升为主站。 
    低优先级的从站被认为更适合于提升,因此如果有三个从站优先级分别是10, 100, 25,sentinel会选择优先级为10的从站,因为它的优先级最低。 
    然而优先级值为0的从站不能执行主站的角色,因此优先级为0的从站永远不会被redis sentinel提升。 
    100 
     requirepass 设置客户端认证密码 关闭 
     rename-command

    命令重命名,对于一些危险命令例如:

    • flushdb(清空数据库)
    • flushall(清空所有记录)
    • config(客户端连接后可配置服务器)
    • keys(客户端连接后可查看所有存在的键)                   

    作为服务端redis-server,常常需要禁用以上命令来使得服务器更加安全,禁用的具体做法是是:

    • rename-command FLUSHALL ""

    也可以保留命令但是不能轻易使用,重命名这个命令即可:

    • rename-command FLUSHALL abcdefg

    这样,重启服务器后则需要使用新命令来执行操作,否则服务器会报错unknown command

    关闭 
    maxclients  设置同时连接的最大客户端数量,一旦达到了限制,Redis会关闭所有的新连接并发送一个"max number of clients reached"的错误 关闭,默认10000 
     maxmemory 不要使用超过指定数量的内存,一旦达到了,Redis会尝试使用驱逐策略来移除键  关闭 
     maxmemory-policy

    当达到了maxmemory之后Redis如何移除数据,有以下的一些策略:

    • volatile-lru,使用LRU算法,移除范围为设置了失效时间的
    • allkeys-lru,根据LRU算法,移除范围为所有的
    • volatile-random,使用随机算法,移除范围为设置了失效时间的
    • allkeys-random,使用随机算法,移除范围为所有的
    • volatile-ttl,移除最近过期的数据
    • noeviction,不过期,当写操作的时候返回错误

    注意,当写操作且Redis发现没有合适的数据可以移除的时候,将会报错

    关闭,noeviction
    appendonly  是否开启AOF,关于AOF后面再说   no
    appendfilename AOF文件名称 appendonly.aof
    appendfsync 

    操作系统实际写数据到磁盘的频率,有以下几个选项:

    • always,每次有写操作都进行同步,慢,但是最安全
    • everysec,对写操作进行累积,每秒同步一次,是一种折衷方案
    • no,当操作系统flush缓存的时候同步,性能更好但是会有数据丢失的风险

    当不确定是使用哪种的时候,官方推荐使用everysec,它是速度与数据安全之间的一种折衷方案

    everysec 
     no-appendfsync-on-rewrite

    aof持久化机制有一个致命的问题,随着时间推移,aof文件会膨胀,当server重启时严重影响数据库还原时间,因此系统需要定期重写aof文件。

    重写aof的机制为bgrewriteaof(另外一种被废弃了,就不说了),即在一个子进程中重写从而不阻塞主进程对其他命令的处理,但是这依然有个问题。

    bgrewriteaof和主进程写aof,都会操作磁盘,而bgrewriteaof往往涉及大量磁盘操作,这样就会让主进程写aof文件阻塞。

    针对上述问题,可以使用此时可以使用no-appendfsync-on-rewrite参数做一个选择:

    • no,最安全,不丢失数据,但是需要忍受阻塞
    • yes,数据写入缓冲区,不造成阻塞,但是如果此时redis挂掉就会丢失数据,在Linux操作系统默认设置下,最坏场景下会丢失30秒数据
     no
     auto-aof-rewrite-percentage 本次aof文件超过上次aof文件该值的百分比时,才会触发rewrite  100 
     auto-aof-rewrite-min-size aof文件最小值,只有到达这个值才会触发rewrite,即rewrite由auto-aof-rewrite-percentage+auto-aof-rewrite-min-size共同保证  64mb
     aof-load-truncated

    redis在以aof方式恢复数据时,对最后一条可能出问题的指令的处理方式: 

    • yes,log并继续
    • no,直接恢复失败
     yes
     slowlog-log-slower-than Redis慢查询的最低条件,单位微妙,即查询时间>这个值的会被记录   10000
     slowlog-max-len Redis存储的慢查询最大条数,超过该值之后会将最早的slowlog剔除 128 
    lua-time-limit 一个lua脚本执行的最大时间,单位为ms 5000
    cluster-enabled 正常来说Redis实例是无法称为集群的一部分的,只有以集群方式启动的节点才可以。为了让Redis以集群方式启动,就需要此参数。 关闭
    cluster-config-file 每个集群节点应该有自己的配置文件,这个文件是不应该手动修改的,它只能被Redis节点创建且更新,每个Redis集群节点需要不同的集群配置文件 关闭,nodes-6379.conf 
     cluster-node-timeout 集群中一个节点向其他节点发送ping命令时,必须收到回执的毫秒数  关闭,15000
    cluster-slave-validity-factor

    如果该项设置为0,不管Slave节点和Master节点间失联多久都会一直尝试failover。

    比如timeout为5,该值为10,那么Master与Slave之间失联50秒,Slave不会去failover它的Master

    关闭,10 
    cluster-migration-barrier

    当一个Master拥有多少个好的Slave时就要割让一个Slave出来。

    例如设置为2,表示当一个Master拥有2个可用的Slave时,它的一个Slave会尝试迁移

    关闭,1
    cluster-require-full-coverage 

    有节点宕机导致16384个Slot全部被覆盖,整个集群是否停止服务,这个值一定要改为no

    =========================

    =========================

  • 相关阅读:
    设计模式(08):结构型模式(二) 桥接模式(Bridge)
    设计模式(07):结构型模式(一) 适配器模式(Adapter)
    设计模式(06):创建型模式(五) 原型模式(Prototype)
    node.js获取cookie
    排序算法[转]
    Observer(观察者)设计模式[转]
    c#发送Http请求
    win+R下的命令
    display:inline、block、inline-block的区别
    Redis安装
  • 原文地址:https://www.cnblogs.com/testzcy/p/10365940.html
Copyright © 2011-2022 走看看