• redis学习笔记


    一,数据类型

    string

    key 的设置约定

    • 数据库中的热点数据命名惯例

      表名:主键名:主键值:字段名

      eg:user:id:1001:age

    业务场景

    Tips1:redis用于控制数据库表主键id,为数据库表主键提供生成策略,保障主键唯一性

    1.分表操作时,避免id重复,可控制数据库主键id生成

    incr num
    decr num

    Tips2: redis控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作;

    2.投票功能,每小时只能投·一票:

    • 投完票后 给该user设置一个标记,并设置过期时间

    • key过期后,方可继续投票

      setex uname 3600 zs

      set uname zs # 再次设置,会覆盖上面

    Tips3:redis 应用于各种结构型和非结构型高热度数据访问加速,及时获取最新数据(后台设置定时刷新策略即可)

    1. 获取 微博大V的文章数和粉丝数,及时获取最新数据

    • 设定用户信息,以用户主键和属性作为key

      user:id:1001:fans 10000
      user:id:1001:blog 500
    • 以json格式存储,定时刷新(也可以使用hash)

    user:id:1001 {id:1001,name:dv, fans:10000, blog:500}

     

    hash

    hash 类型数据操作注意事项

    1. hash 类型下的value只能存储字符串,不允许存储其它数据类型,不存在嵌套现象;

    2. 每个hash可存储 2^32 - 1 个键值对

    3. hash设计初衷不是为了存储大量对象而设计的,不可滥用,更不可将hash作为对象列表使用

     

    业务场景

    Tips4: redis应用于购物车数据存储设计

    电商网站购物车设计与实现

    解决方案:

    • 以客户id为key,每位客户创建一个hash存储结构存储对应的购物车信息

    • 将商品编号作为field,购买数量作为value存储

    • 添加商品:追加全新的field与value

    • 浏览:遍历hash hgetall user

    • 更改数量:自增/自减,设置value

    • 删除商品: 删除field

    • 清空: 删除key

    加速购物车的呈现:

    1.用户对应购物车中只存储不同id商品的数量(一个用户购物车对应一个hash)

    hmset user:003 g01:nums 100 g02:nums 200

    2.再利用一个独立hash专门用于存储商品的信息,所有商品信息走公共部分获取

    当然所有商品信息存到一个hash也会影响速度(可以按商品分类存储到多个hash)

    3.(不能一开始就把全部商品加进去)用哪个商品,往hash添加哪个商品

    但是不能每个人添加一次商品,就又将它加入一次;可以使用hsetnx

    hsetnx key field value   # 当前key不存在该field才往里加,有则不管

     

    商家的抢购活动

    解决方案:

    • 商家id为key,参与抢购商品id为field,商品数为value

    • 抢购时使用降值方式控制产品数

    • 超卖问题暂没做考虑

    string存储对象(json) 与hash存储对象

    strinf存储对象:适合只用于读取的场景

    hash存储对象:适合数据修改的场景

     

    list

    • list类型 底层是基于双向链表的存储结构 (查询效率相对较慢)

    list 类型数据基本操作

    • 添加/修改数据

      lpush key value1 【value2】
      rpush key value1 【value2】
    • 获取数据

      lrange key start stop
      lindex key index
      llen key
    • 获取并移除数据

      lpop key
      rpop key

    list 类型数据扩展操作

    • 规定时间内获取并移除数据(阻塞式数据获取)

      blpop key1 【key2】 timeout
      brpop key1 【key2】 timeout
    • 移除指定元素

      lrem key count value

     

    list类型数据操作注意事项

    • list中保存的都是string类型 ,数据容量有限,最多2^32 - 1 个元素

    • list具有索引概念,但通常操作数据以队列或栈的形式

    • 获取全部数据操作结束索引设 -1

     

    业务场景

    1.可以对数据进行分页操作

    通常第一页来自于list(读取缓存),第二页及更多信息通过数据库加载

    Tips:redis 适用于具有操作先后顺序的数据控制

    2.朋友圈点赞,取消点赞

    点赞的名称是带有顺序,且有多个

    rpush key name
    lrem key count value # 可用于取消点赞

    3.新浪微博中个人用户关注列表需要按用户的关注顺序进行展示,粉丝列表需要将最近关注的粉丝列在前面

    4.新闻,资讯类网站将最新的新闻按照时间繁盛的顺序展示

    5.如何保障多台服务器操作日志的统一顺序输出

    Tips:redis 应用于最新消息的展示

    • 依赖list的数据具有顺序的特征对信息进行管理

    • 使用队列模型解决多路信息排队汇总合并的问题 (多台服务器的日志汇总)

    • 使用栈模型解决最新消息的问题

     

    set

    • 新的存储需求:存储大量的数据,在查询方面提供更高的效率

    • 需要的存储结构:能够保存大量的数据,高效的内部存储机制,便于查询

    • set类型:与hash存储结构完全相同,只保存健,不存储值(nil), 并且不允许重复

    set 类型数据的基本操作

    • 添加数据

      sadd key member1 【member2】
    • 获取全部数据

      smembers key
    • 删除数据

      srem key member1 【member2】
    • 获取集合数据总量

      scard key
    • 判断集合中是否包含指定数据

      sismember key member

     

    set 类型数据的扩展操作

    • 随机获取集合中指定数量的数据

      srandmember key 【count】
    • 随机获取集合中某个数据并将该数据移出集合

      spop key

      业务场景使用:

      1.如推送热点信息服务,

      第一种:推荐过后的数据,依然有可能继续推送

      第二种:推荐过后的数据剔除,下次不再推送

    • 求两个集合的交,并,差集

      sinter key1 【key2】
      sunion key1 【key2】
      sdiff key1 【key2】
    • 求俩集合的交,并,差集并存储到指定集合中

      # destination 为目标集合
      sinterstore destination key1 【key2】
      sunionstore destination key1 【key2】
      sdiffstore destination key1 【key2】
    • 将指定数据从原始集合中移动到目标集合

      # source:原集合, destination:目标集合, member:数据
      smove source destination member

      业务场景使用:

      2.获取共同好友,共同关注列表

    set类型数据注意事项

    • set类型不允许数据重复,如果添加的数据在set中已经存在,后面的添加操作将失败(只保留一份)

    • set虽然与hash存储结构相同,但是无法启用hash中存储值的空间

    业务场景

    Tips:redis应用于随机推荐类信息检索,例如热点歌曲,热点新闻,热点旅游线路,大v等的推荐。

    srandmember key 【count】
    spop key

    Tips: redis应用于同类信息的关联搜索,二度关联搜索,深度关联搜索

    • 显示共同好友/关注(一度)

    • 由用户A出发,获取到好友用户B的好友信息列表(一度)

    • 由用户A出发,获取到好友用户B的购物清单列表(二度)

    • 由用户A出发,获取到好友用户B的游戏充值列表(二度)

    Tips: redis应用于同类型不重复数据的合并操作(合并去重)

    3.公司旗下网站推广,统计网站的PV(访问量),UV(独立访客), IP(独立IP)

    • PV:网站被访问的次数,可以通过页面刷新来提高访问量(点开一次链接就是一次访问)

    • UV:网站被不同用户访问的次数,可以通过cookie来区别不同用户,统计访问量;相同用户切换IP地址,UV不变;

    • IP:网站被不同IP地址访问的总次数,可以通过ip地址统计访问量;相同IP不同用户访问,IP不变

    • 利用set集合的数据去重特征,记录各种访问数据

    • 建立string类型,利用incr 统计日访问量(PV)

    • 建立set模型,记录不同cookie数量或不同IP数量

      • 每进来一个ip记录一下,重复的ip将存储失败;

    Tips:redis应用于同类型数据的快速去重

     

    sorted_set 类型

    • 新的存储模型,可以保存可排序的数据

    • 在set的存储结构基础上添加可排序字段score

    基本操作

    • 添加数据

      zadd key score1 member1 [score2 meber2]
    • 获取全部数据

      zrange key start stop [withscores]
      zrevrange key start stop [withscores]
    • 删除数据

      zrem key member [member...]
    • 按条件获取数据

      zrangebyscore key min max [withscores][limit]
      zrevrangebyscore key min max [withscores][limit]
    • 按条件删除数据

      zremrangebyrank key start stop
      zremrangebyscore key min max
    • 获取集合数据总量

      zcard key
      zcount key min max
    • 集合交并集操作

      zinterstore destination numkeys key [key...]
      zunionstore destination numkeys key [key...]
      # 求交集时同时还会对score的求和
      # 附加参数
      - aggregate max/min  // 求最大/最小值

    Tips: redis应用于计数器组合排序功能对应的排名

    • 获取数据对应的索引(排名)

      zrank key member
      zrevrank key member
      
    • score值获取与修改

      zscore key member
      zincrby key num member
      

      业务场景:

      网站上的排名,人气排名,票房排名;排序之后取具体排名或票数

    注意事项

    • score保存的数据存储空间是64位,若为整数,范围是-9007199254740992~9007199254740992

    • score保存的数据若为小数,可以是一个双精度的double值,但可能会丢失精度,使用要慎重

    • sorted_set 底层是基于set结构,数据不能重复,若重复设置,则会覆盖,保留最后一次修改结果;(但返回依然是失败0)

    业务场景

    Tips:redis应用于定时任务执行顺序管理或任务过期管理

    视频限时vip,限时投票等

    带权重的消息/任务队列

     

    数据类型实践案例

    Tips: redis应用于限时按次结算的服务控制

    例如某些服务,一分钟内只能使用5次;

    基础方案:

    # 先判断key是否为空
    # setex key 60 1 # 第一次进来值设置1,生命周期位60s
    # incr 1 # 每次使用+1
    # 每次调用,判断 key是否>=5;是则禁止访问

    改良方案:

    # 为了取消每次判定,第一次值设置为string类型允许保存的最大值9223372036854775807 - 允许次数; 通过超过最大值时报错来限制操作
    setex key 60 9223372036854775807-5 # 第一次进来值设置1,生命周期位60s
    incr 1 # 每次使用+1

    微信消息,按好友最晚来信息时间进行排序,时间越近的摆在最上面;

    • 依赖list的数据具有顺序的特征对消息进行管理,将list结构作为栈使用

    • 对置顶与普通会话分别创建独立的list分别管理

    • 当某个list中接收到用户消息后,将消息发送方的id从list的一侧加入list

    • 多个相同id发出的消息反复入栈会出现问题,在入栈之前无论是否具有当前id对应的消息,先删除对应id

    • 推送消息时先推送置顶会话list,再推送普通会话list,推送完成的list清除所有数据

    • 消息的数量,就直接采用计数器形式记录,伴随list操作同步更新

     

    二,key的扩展操作(查询模式)

    1.查询key

    keys pattern

    2.查询模式规则

    • *:匹配任意数量的任意符号

    • ?:匹配一个任意符号

    • []:匹配一个指定符号

      keys *          查询所有
      keys it*        查询所有以it开头
      keys *it        查询所有以it结尾
      keys ??it       查询所有前面两个任意字符,后面以it结尾
      keys user:?     查询所有以user:开头,最后一个字符任意
      keys u[st]er:1  查询所有以u开头,以er:1结尾,中间包含一个字母,st

     

    三,DB相关操作

    • 数据移动

      move key db
      
    • 数据清除

      dbsize    查看数据库有多少个key
      flushdb   清除当前数据库
      flushall 清除所有数据库

     

    四,linux下操作

    1.安装(center OS)

    1.下载redis包,解压tar -xvf 文件名
    2.进入解压的目录 make install
    3.进入src目录可以看到所有安装的东西,运行redis-server即可启动
    

     

    2.Redis服务启动

    指定端口启动

    当需要启动多台redis服务时,需要切换端口,

    启动服务端:

    
    

    启动连接客户端:

    redis-cli -p 6382
    

    以配置文件的形式启动

    生产环境中多以自定义配置文件启动。

    安装的redis目录下有一个redis.conf的文件,包含了一些启动项的信息,需要配置时可以进入查看;

    以默认配置启动:

    redis-server
    
    redis-server --port 6379  # 指定端口
    
    redis-server --port 6380
    

    自定义配置文件启动:

    1.cdredis安装目录下:
    make dir data  
    redis-4.0.0/data  用于存放redis操作生成的文件

    2.redis目录下创建一个 配置文件管理目录conf(用于存放多个启动文件),进入conf目录下:
    创建一个配置文件
    make dir redis-6379.conf
    编辑配置:
    vim redis-6379.conf
    添加内容:
    port 6379
    daemonize yes   # 以守护进程的方式启动 no:控制台会打印日志信息 yes:后台启动,控制台不再打印
    logfile "6379.log"   # 后台启动时日志文件保存的位置
    dir redis-4.0.0/data  # 对应生成的文件放在该位置,比如存放生成的日志文件

    3.启动,在redis安装目录下:
    redis-server conf/redis-6379.conf

    需要创建多个配置文件时,只需要复制并修改端口和日志文件名即可;

    可以通过查看进程查看是否启动: ps -ef | grepredis 。

     

    五,持久化

    redis持久化方式分为两种:RDB(对数据进行快照保存)AOF(以日志保存操作记录)

    RDB

    1.RDB启动方式 -- save指令

    注意:会阻塞当前redis服务器,线上环境不建议使用

    • 命令

      save

    • 作用

      手动执行一次保存操作,保存会生成一个 .rdb 的文件,保存当前快照信息;

    save指令相关配置

    • dbfilename dump.rdb

      • 说明:设置本地数据库文件名,默认为dump.rdb

      • 经验:通常设置为dump-端口号.rdb

    • dir

      • 说明:设置存储.rdb文件的路径

      • 经验:通常设置成存储空间较大的目录中,目录名为data

    • rdbcompression yes

      • 说明:设置存储本地数据库时是否压缩数据,默认为yes,采用LZF压缩

      • 经验:通常默认为开启状态,如果设置为no,可以节省CPU运行时间,但存储文件变得巨大

    • rdbchecksum yes

      • 说明:设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行

      • 经验:通常默认为开启状态,如果设置为no,可以节约读写型过程约10%时间消耗,但存在数据损坏风险

      # 启动配置conf文件中添加内容:
      	port 6379
      	daemonize yes # 以守护进程的方式启动 no:控制台会打印日志信息 yes:后台启动,控制台不再打印
      	logfile "6379.log"   # 后台启动时日志文件保存的位置
      	dir redis-4.0.0/data  # 对应生成的文件放在该位置,比如存放生成的日志文件
      	
      	dbfilename dump-6379.rdb
      	rdbcompression yes
      	rdbchecksum yes
      

      数据恢复:当使用save命令保存,生成了.rdb文件后,断开服务器;再次启动服务时,会从磁盘加载保存的数据;

    save指令工作原理

    由于redis是单线程操作,当多个客户端进行命令操作时,会单线程任务执行序列中的命令;

    注意:save指令的执行会阻塞当前redis服务器,知道当前RDB过程完成为止,有可能造成长时间阻塞,影响服务器性能,线上环境不建议使用

     

    2.RDB启动方式 -- save指令

    • 命令

      bgsave

    • 作用

      手动启动后台保存操作,但是不是立即执行

      手动启动后,会在合适的时间后台去完成操作

    bgsave指令配置

    在save指令配置基础上再添加一个配置

    • stop-writes-on-bgsave-error yes

      • 说明:后台存储过程中如果出现错误现象,是否停止保存操作

      • 经验:通常默认为开启状态

    bgsave指令工作原理

    1.客户端发送指令
    2.返回消息:background saving started
      同时调用fork函数生成子进程
    3.子进程中保存rdb文件
    4.返回成功消息
    

    bgsave指令不会加入到任务执行序列中,而是创建子进程去执行;

    注意:bgsave命令是针对save阻塞问题做的优化,redis内部所有涉及到RDB操作都建议采用bgsave的方式,save命令基本可以放弃使用。

     

    3.RDB启动方式 -- 自动执行(save配置)

    使用save配置自动保存数据 -- 也是使用bgsave指令

    • 配置

      save second changes
      
    • 作用

      在满足限定时间范围内key的变化数量达到指定数量即进行持久化;

      若某次限定时间段内key变化没有达到指定数量,那将在下次满足条件时,将之前的数据一起保存。

    • 参数

      second:监控时间范围

      changes:监控key的变化

    • 位置

      在conf文件中进行配置,编辑配置文件conf,添加:

      ......
      save 300 10
      
    • 范例

      save 900 1
      save 300 10
      save 60 10000
      

    save配置原理

    怎样会影响key变化数量加一

    1.会对数据产生影响
    2.真正产生了影响(值没有变不行)
    3.不进行数据对比(连续两次set同一个东西 影响书+2)
    

    注意:

    1.save配置要根据实际业务情况进行设置,频度过高和过低都会出现性能问题,结果可能是灾难性的
    2.save配置中second与changes设置通常具有互补对应关系,尽量不要设置成包含性关系
    3.save配置启动后执行的是bgsave操作
    

    4.RDB特殊启动方式

    • 全量复制

      主从复制中用到

    • 服务器运行过程中重启

      debug reload

    • 关闭服务器时指定保存数据

      shutdown save

    5.启动方式对比

    方式savebgsave
    读写 同步 异步
    阻塞客户端指令
    额外消耗内存
    启动新进程

    6.RDB优缺点

    优点

    • RDB是一个紧凑压缩的二进制文件,存储效率较高

    • RDB内部存储的是redis在某个时间点的数据快照,非常适用于数据备份,全量复制等场景

    • RDB恢复数据的速度要比AOF快很多

    • 应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复

    RDB缺点

    • RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大的可能性丢失数据

    • bgsave指令每次运行要fork操作创建子进程,要牺牲掉一些性能

    • redis的众多版本中未进行RDB文件格式版本统一,有可能出现各版本服务器之间数据无法兼容现象

     

    AOF

    1.AOF写数据过程

    1.先将执行过的命令写入缓存区
    2.将命令写入AOF文件中,AOF写命令会刷新缓存区
    

     

    2.AOF写数据三种策略(appendfsync)

    • always(每次):每次操作均同步到AOF文件中,不建议使用

      • 数据零误差

      • 性能较低

    • everysec(每秒):每秒将缓冲区的指令同步到AOF文件中,建议使用,也是默认配置

      • 数据准确性较高

      • 性能较高

      • 在系统突然宕机的情况下丢失1秒内的数据

    • no(系统控制):由操作系统控制每次同步到AOF文件的周期,整体过程不可控

     

    3.AOF功能开启

    配置

    配置文件conf中添加:

    appendonly  yes/no  # 是否开启AOF持久化功能,默认为不开启

    appendfsync  always/everysec/no  # AOF写数据策略,默认everysec

    当服务启动时,data目录下会生成一个 .aof 的文件

     

    4.AOF重写

    随命令不断写入,文件越来越大,reids引入AOF重写机制压缩体积;

    AOF文件重写:就是将redis进程内的数据转化为写命令同步到aof文件;

    简单说就是将对同一个数据的若干个命令执行结果转化成最终结果进行记录

    作用

    • 降低磁盘占用量,提高磁盘效率

    • 提高持久化效率,降低持久化写时间,提高IO性能

    • 降低数据恢复耗时,提高数据恢复效率

    重写规则

    • 进程内已超时的数据不再写入文件

    • 忽略无效指令,重写时使用进程内数据直接生成,这样aof文件只保留最终数据的写入命令

      • 如del key1, set key 1,set key 22,incr 2,incr 2 等重复命令

    • 对同一数据的多条写入命令合并为一条命令

      • 如lpush list1 a、lpush list1 b、lpush list1 c 合并为 lpush list1 a b c.

      • 为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zse等类型,每条指令最多写入64个元素

    重写方式

    1. 手动重写:bgrewriteaof

     

    1. 自动重写:auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage

    • 自动重写触发条件设置

      两种条件,可以只配置一种

      1.auto-aof-rewrite-min-size    size大小
      2.auto-aof-rewrite-percentage  percentage百分比
      
    • 自动重写触发比对参数(运行指令info Persistence获取具体信息)

      aof_current_size   # aof文件当前大小
      aof_base_size     # aof 基础大小
      
    • 自动重写触发条件

      两种条件中满足一种就能触发aof重写

      1. aof_current_size > auto-aof-rewrite-min-size
      
      2. (aof_current_size -    	aof_base_size)/aof_base_size >= auto-aof-rewrite-percentage
      

    bgrewriteaof指令工作原理

    1.客户端发送指令
    2.返回消息:background append only file rewriting started
      同时调用fork函数生成子进程
    3.子进程中 重写aof文件
    4.返回成功消息
    

     

    重写流程

     

     

     

    RDB与AOF区别

    对比

    持久化方式RDBAOF
    占用存储空间 小(数据级:压缩) 大(指令级:重写)
    存储速度
    恢复速度
    数据安全性 会丢失数据 依赖策略决定
    资源消耗 高/重量级 低/轻量级
    启动优先级

     

    使用选择

    对数据非常敏感,建议使用默认的AOF持久化方案

    • AOF持久化策略使用everysecond,每秒一次;最多丢失一秒数据

    • 注意:aof文件存储体积较大,恢复速度较慢

    数据呈现阶段有效性,建议使用RDB持久化方案

    • 数据可以良好做到阶段内无丢失,恢复速度较快

    综合对比

    • ...

     

    持久化场景

    大多都需要综合考虑,也只是建议;任务队列/消息队列一般使用各种MQ技术

     

    六,事务

    基本操作

    1.使用事务

    • 开启事务

      # 设定事务开启的位置,此指令执行后,后续所有指令均加入到事务中
      multi
      
    • 执行事务

      # 设定事务的结束位置,同时执行事务,与mutil成对使用
      exec
      

    注意:加入事务的命令暂时进入到任务队列中,并不立即执行,当执行exec命令才开始执行

    • 取消事务

      # 终止当前事务的定义,发生在multi之后exec之前
      discard
      

     

    2.事务工作流程

     

    3.注意事项

    • 定义事务过程中,命令格式输错,事务中的命令将都不会执行

    • 定义事务过程中,命令格式正确,但无法执行(例如对str进行incr),执行失败,但事务中的正确命令将继续被执行。

    注意:第二种,已经执行的命令无法回滚,需要程序员将自己回滚(一般不能出这种错);相对来讲redis事务用的也偏少;

     

    事务-锁

    1.基于特定条件的事务执行-锁

    • 对key添加监视锁,在一个事务过程中,执行exec前,如果key发生了变化(被其他客户端改变),终止事务执行,所有操作全取消;

      watch key1 【key2】
      
    • 取消对所有key的监视

      unwatch
      

    注意:watch监控只能在事务外执行,操作示例

    set name aa
    set age 123
    wacth name
    mutil
    set name bb
    get name
    set age222
    # 在该事务未执行exec前,此时另一个客户端执行:
    set name ccc
    # 监听的name被其他客户端修改
    # 当前客户端再去执行exec时,事务终止,事务中的操作都不会被执行
    exec  # 将返回nil(正常返回事务中所有指令执行的结果)
    

    tips:redis应用于基于状态控制的批量执行

    案例:双十一补货,四个管理员同时具备补货权限,但一个人补货后,其他人将不需要再补货;同一时间需防止多人同时补货;

    • 监听补货的商品数,一旦变化,其他人的补货操作将不再被执行

     

    2.基于特定条件的事务执行 -分布式锁(同步锁)

    案例:为解决秒杀中的超卖问题

    1. 使用setnx设置一个公共锁

    # 基于string类型setnx的特性:仅当key不存在时设置
    setnx lock-key value   # key 和value 不重要 自定义
    

    利用setnx命令的返回特征,有值则返回设置失败0,无值则返回设置成功1

    • 对于返回设置成功的,拥有控制权,进行下一步的具体业务操作

    • 对于返回设置失败的,不具有控制权,排队或等待

    1. 操作完毕通过del操作释放锁

      del lock-key
      

    注意:这是一种设计概念,依赖规范保障(必须锁同一把锁)

    tips :redis 应用基于分布式锁对应的场景控制

     

    3.分布式锁改良--死锁

    背景:

    当加了锁的客户端,中途宕机,来不及释放锁,其他要进行该业务的客户端将一直等待,即出现死锁;
    

    解决方案

    使用expire为锁key添加时间限定, 到限定时间不释放,放弃锁

    expire lock-key 秒
    pexpire lock-key 毫秒
    

    由于操作通常都是微妙或毫秒级,因此过期时间不宜设置过大,具体需测试后确认:

    • 例如:持有锁的操作最长执行时间127ms,最短7ms

    • 测试百万次最长执行时间对应命令的最大耗时,测试百万次网络延迟平均耗时

     

    七,数据删除策略

    删除策略

    主要针对具有时效性的key的删除管理

    1.定时删除

    创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务立即执行对key的删除操作

    优缺点:节约内存,但cpu压力大——以时间换空间

     

    2.惰性删除

    数据到达过期时间,不做处理,等到下次访问该数据时:

    • 如果未过期,返回该数据

    • 发现已过期,删除,返回不存在

    具体实现:每次获取数据时都会调用 expireIfNeeded() 函数,检查key是否过期

    优缺点:节约cpu性能,发现必须删除时才删除,但内存压力大,出现长期占用内存情况——以空间换时间

     

    3.定期删除

    • 内存定期随机清理

    • 每秒花费固定的cpu资源维护内存

    • 随机抽查,重点抽查

     

    逐出算法(淘汰策略)

    影响数据逐出的相关配置

    • 最大可使用内存

      maxmemory
      

      占用物理内存的比例,默认值为0,表示不限制;

    • 每次选取待删除数据的个数

      maxmemory-samples
      

      选取数据时并不会全库扫描,导致严重的性能消耗,降低读写性能。因此采用随机获取数据的方式作为待检测删除数据

    • 删除策略

      maxmemory-policy
      

      达到最大内存后,对被挑选出来的数据进行删除的策略

    • 使用info命令输出监控信息,查询缓存hit 和 miss 的次数,根据业务需求调优redis配置

      两个信息:

      • keyspace_hits : 命中次数

      • keyspace_misses:丢失次数

     

    八,服务器配置——redis.conf 配置

    服务器基础配置

    服务器端设定

    • 设置服务器以守护进程的方式运行

      daemonize yes/no
      
    • 绑定主机地址:绑定后只允许通过该ip访问服务器

      bind 127.0.0.1
      
    • 设置服务器端口号

      port 6379
      
    • 设置数据库数量

      databases 16
      

    日志配置

    • 设置服务器以指定日志记录级别

      loglevel debug/verbose/notice/warning
      
    • 日志记录文件名

      logfile 端口号.log
      

    注意:日志级别开发期设置为verbose即可,生产环境中配置notice,简化日志输出量,降低写日志io的频度;

     

    客户端配置

    • 设置同一时间最大客户连接数,默认0无限制。当客户端连接到达上限,Redis会关闭新的连接

      maxclients 0
      
    • 客户端闲置等待最大时长,达到最大值后关闭连接。如需关闭该功能,设置为0

      
      

    多服务器快捷配置

    • 导入并加载指定配置文件信息,用于快速创建redis公共配置较多的redis实例配置文件,便于维护

      include /path/server-端口号.conf
      

     

    企业级解决方案

    1.缓存预热

    缓存预热:指系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求时,先查询数据,然后再将数据缓存的问题。用户直接查询事先被预热的缓存数据。

     

    2.缓存雪崩

    缓存雪崩:是指瞬间大量数据过期,导致对数据库服务器造成压力。

    如果能够有效避免过期时间集中,可以有效解决雪崩现象的出现(约40%),配合其他策略一起使用,并监控服务器的运行数据,根据运行记录做出快速调整。

     

     

     

    3.缓存击穿

    缓存击穿:单个key高热数据过期的瞬间,数据访问量较大,未命中redis后,发起大量对同一数据的请求到数据库,造成压力;

     

     

     

    4.缓存穿透

    缓存穿透:访问了不存在的数据,跳过了合法数据的redis数据缓存阶段,每次访问数据库,导致对数据库服务器造成压力。

    通常此类数据的出现量是一个较低值,当出现量很高时,多半是考虑黑客攻击。

    无论是黑名单还是白名单,都是对整体系统的压力,危机解除后应尽快移除。

     

     

     

    5.性能指标监控

     

    命令

    benchmark

     

    monitor :打印服务器调试信息

     

    slowlog

     

  • 相关阅读:
    《中小学生Python编程入门指南》1.1 什么是编程
    《中小学生Python编程入门指南》前言
    简单的番茄工作法倒计时(源码)
    关于AE
    Blender2.5快捷键
    关于Blender
    随意设置控件每一个角的倒角
    关于多个block问题
    UICollectionViewCell--查找cell上的按钮点击后,对应的是哪个cell
    UIMenuItem
  • 原文地址:https://www.cnblogs.com/Deaseyy/p/13341746.html
Copyright © 2020-2023  润新知