• Redis


    Redis

    Redis简介

    Redis是单线程+多路IO复用

    ​ 多路复用是指使用一个线程来检查多个文件描述符(Socket)的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)。

    Redis相关配置

    Redis的默认安装目录是 /usr/local/bin

    Redis配置文件redis.conf

    daemonize 让服务后台启动
    include 引入配置文件
    计量单位说明 大小写不明感
    timeout 一个空闲的客户端维持多少时间关闭,0为永不关闭
    tcp keepalive 对访问客户端的一种心跳检查,每个n秒检测一次
    pidfile 存放pid文件的位置,每个实例会产生一个不同的pid文件
    log level 四个级别根据使用阶段来选择,生产环境选择notice 或者warning
    syslog 是否将redis日志输送到linux系统日志服务中
    syslog-ident 日志的标志
    database 设置库的数量 默认16
    syslog-facility 输出日志的设备
    maxclient 最大客户端连接数
    1. ip地址的绑定 bind
    • 默认情况bind=127.0.0.1只能接受本机的访问请求

    • 不写的情况下,无限制接受任何ip地址的访问

    • 生产环境肯定要写你应用服务器的地址

    • 如果开启了protected-mode,那么在没有设定bind ip且没有设密码的情况下,Redis只允许接受本机的相应

    1. tcp-backlog
    • 可以理解是一个请求到达后至到接受进程处理前的队列.

    • backlog队列总和=未完成三次握手队列 + 已经完成三次握手队列

    • 高并发环境tcp-backlog 设置值跟超时时限内的Redis吞吐量决定

    3)security

    • 命令行修改密码
    • image-20200923192041004

    4)maxmemory

    • 设置Redis可以使用的内存量。一旦到达内存使用上限,Redis将会试图移除内部数据,移除规则可以通过maxmemory-policy来指定。如果Redis无法根据移除规则来移除内存中的数据,或者设置了“不允许移除”,那么Redis则会针对那些需要申请内存的指令返回错误信息,比如SET、LPUSH等。
    1. Maxmemory-policy
    • volatile-lru:使用LRU算法移除key,只对设置了过期时间的键

    • allkeys-lru:使用LRU算法移除key

    • volatile-random:在过期集合中移除随机的key,只对设置了过期时间的键

    • allkeys-random:移除随机的key

    • volatile-ttl:移除那些TTL值最小的key,即那些最近要过期的key

    • noeviction:不进行移除。针对写操作,只是返回错误信息

    1. Maxmemory-samples
    • 设置样本数量,LRU算法和最小TTL算法都并非是精确的算法,而是估算值,所以你可以设置样本的大小。一般设置3到7的数字,数值越小样本越不准确,但是性能消耗也越小。

    Redis的数据类型

    image-20200923152902768

    key
    keys * 查看当前库的所有键
    exists 判断当前某个键是否存在
    type 查看键的类型
    del 删除某个键
    expire 为键值设置时间
    ttl 查看key的过期时间,-1表示用不过期,-2表示已过期
    dbsize 查看当前库的key的数量
    Flushdb 清空当前库
    Flushall 通杀全部库
    String
    1. String是Redis中的最基本数据类型
    2. String类型是二进制安全的。意味着String可以包含任何数据:jpg图片,序列化对象
    get 查询key对应的值
    set 添加键值对
    append 将给定的追加到原值的末尾
    strlen 获取值的长度
    setnx 只有在key不存在的时设置key值
    incr 将key中存储的数字值增1,只对数字操作,如果为空,新增为1
    decr 将key中存储的数字值减1,只对数字操作,如果为空,新增为-1
    incrby/decrby <步长> 将key中存储的数字值增减,自定义步长
    mset 同时设置一个或多个key-value对
    mget 同时获取一个或多个value
    msetnx 同时设置一个或多个key-value对,当且仅当所有给定的key都不存在
    getrange <起始位置> <结束位置> 获得值的范围,类似java中的substring
    setrange <起始位置> 覆盖所存储的字符串值,从<起始位置>开始
    setex <过期时间> 设置键值的同时,设置过去时间,单位秒
    getset 以新换旧,设置了新值的同时获取旧值
    1. 详说 incr key 操作的原子性

    所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。

    在单线程中, 能够在单条指令中完成的操作都可以认为是" 原子操作",因为中断只能发生于指令之间。

    在多线程中,不能被其它进程(线程)打断的操作就叫原子操作。

    List

    单键多值

    Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)

    它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差

    image-20200923161816810

    lpush/rpush 从左边/右边插入一个或多个值。
    lpop/rpop 从左边/右边吐出一个值。 值在键在,值光键亡。
    rpoplpush 列表右边吐出一个值,插到列表左边
    lrange 按照索引下标获得元素(从左到右)
    lindex 按照索引下标获得元素(从左到右)
    llen 获得列表长度
    linsert before 的后面插入 插入值
    lrem 从左边删除n个value(从左到右)
    Set
    1. set跟list功能相同,set具有自动排重功能
    2. Set 是string类型的无序集合。它的底层是一个value为null的hash表,所以添加,删除,查找的复杂度都是O(1)
    sadd .... 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
    smembers 取出该集合的所有值。
    sismember 判断集合是否为含有该值,有返回1,没有返回0
    scard 返回该集合的元素个数。
    srem .... 删除集合中的某个元素。
    spop 随机从该集合中吐出一个值。
    srandmember 随机从该集合中取出n个值。 不会从集合中删除
    sinter 返回两个集合的交集元素。
    sunion 返回两个集合的并集元素。
    sdiff 返回两个集合的差集元素。
    Hash
    1. hash 是一个键值对集合
    2. hash是一个string类型的field和value的映射表,hash特别适合用于存储对象
    3. 类似Map<String,Object>
    分析一个问题:先有一个javaBean对象,在Redis中如何存
    1. 用户id为key,value为JavaBean中序列化后的字符串
    • image-20200923164325049

    • 缺点: 每次修改用户的某个属性需要,先反序列化改好后再序列化回去。开销较大

    image-20200923164657854

    • 缺点:用户id数据冗余

    • image-20200923165013699

    • l 第三种方案: 通过 key(用户ID) + field(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题

    hset 集合中的 键赋值
    hget 集合 取出 value
    hmset ... 批量设置hash的值
    hexists key 查看哈希表 key 中,给定域 field 是否存在。
    hkeys 列出该hash集合的所有field
    hvals 列出该hash集合的所有value
    hincrby 为哈希表 key 中的域 field 的值加上增量 increment
    hsetnx 将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在
    zset(sirted set)
    1. 跟set相似,是一个没有重复元素的字符串集合。但是zset的成员关联一个score。按照这个score来排序
    2. 因为元素是有序的。可以根据score或者position来获取一个范围的元素。访问中间元素也是很快的
    zadd ... 将一个或多个 member 元素及其 score 值加入到有序集 key 当中
    zrange [WITHSCORES] 返回有序集 key 中,下标在 之间的元素 带WITHSCORES,可以让分数一起和值返回到结果集。
    zrangebyscore key min max [withscores] [limit offset count] 返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。
    zrevrangebyscore key max min [withscores] [limit offset count] 同上,改为从大到小排列。
    zincrby 为元素的score加上增量
    zrem 删除该集合下,指定值的元素
    zcount 统计该集合,分数区间内的元素个数
    zrank 返回该值在集合中的排名,从0开始。

    Redis事务

    redis的事务中的所有命令都会序列化,按顺序的执行。执行过程中,不会被其他客户端发来的命令请求打断。

    作用:串行多个命令防止别的命令打断

    1)multi ,exec,discard

    开启事务:输入multi,之后输入的命令会依次进入命令队列,但不执行。

    直到输入Exec后,redis依次执行命令队列中的命令

    2)组队中可以用discard放弃组队

    image-20200923211912628

    2)事务中的错误处理
    1. 组队中某个命令出现了报告错误,执行时整个的所有队列会都会被取消。

    image-20200923212100108

    1. 如果执行阶段某个命令报出了错误,则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚。

    image-20200923212109381

    3)为什么要有事务

    悲观锁:每次获取数据的时候会认为别人会修改数据, 所以每次在拿这个数据的时候都会上锁。

    传统的关系型数据库就是这种锁机制,如表锁,行锁等,读锁,写锁等

    image-20200924142019629

    乐观锁:认为每次拿数据的时候别人不会修改,就不上锁。但在更新的时候会判断别人是否更新这个数据,使用版本号等机制。乐观锁适用于多读应用类型。

    image-20200924142055144

    Redis持久化

    Redis提供了2个不同形式的持久化方式 RDB 和 AOF

    RDB
  • 相关阅读:
    日志类
    sql查询数据并导出问题
    高并发系统设计(十七):【系统架构】微服务化后,系统架构要如何改造?
    高并发系统设计(十五):【消息队列】如何降低消息队列系统中消息的延迟?
    高并发系统设计(十四):【消息队列】如何消息不丢失?并且保证消息仅仅被消费一次?
    高并发系统设计(十三):消息队列的三大作用:削峰填谷、异步处理、模块解耦
    高并发系统设计(十二):【缓存的正确使用姿势】缓存穿透了怎么办?如何最大程度避免缓存穿透
    高并发系统设计(十一):【缓存的正确使用姿势】缓存如何做到高可用?
    ThinkPad X1 Carbon无法识别第二屏幕
    如何设置两个TPLink路由器桥接
  • 原文地址:https://www.cnblogs.com/mankaixin/p/13906737.html
Copyright © 2020-2023  润新知