REDIS

作者: ZzGo12 | 来源:发表于2018-06-13 00:18 被阅读0次

    NoSQL = Not Only SQL.
    高并发读写 会导致关系型数据库压力过大


    NOSQL分类

    NOSQL优点:数据之间无关系, 易拓展, 灵活的数据模型, 大数据量,高性能, 高可用。

    redis: 高性能键值对数据库


    支持的数据结构 redis应用场景 jedis连接步骤

    Jedis配置

    1. 写JedisConfig 配置连接数 账号密码 连接时间 地址 等等
    2. 写service 要进行哪些操作(其中需要的一些获得jedis的对象配置在@configuration中 比如jedispool什么的)
    3. 封装Prefix(prefix, expires) 使得 key不冲突,按模块区分
    image.png

    字符串常用操作:

    1. 当做整形用: incr 、 incrby、del...
    2. 当做字符串: set、 append…

    哈希表常用操作:

    1. hset 表名 key value(存值) hmset 表名 key1 value1 key2 value2...(多)
    2. hget 表名 key(取值) hmget 表名 key1 key2...(多)
    3. del 表名(删除整个集合) hdel 表名 key删除这个key value
    4. hincrby 表名 key number(要增加的值) 给key里的value+number

    列表常用操作:

    1. lpush/rpush 表名 value1,value2,value3...
    2. lrange 表名 from to ->[from, to]里的元素 从0开始并且包括尾索引
    3. lpop/rpop 表名
    4. llen 表名
    5. 常用于消息队列, 多个程序之间的通信。 生产者:一个程序往list中添加元素。 消费者:一个程序往list中取走元素。为防止消费者取走后没有正常消费(出现了一些异常等等), 通常需要使用poppush操作,在取走的同时放进一个备份队列,当确定无误后,再将备份队列中的数据删除。


      消息通信

    集合(set) 常用命令:

    1. sadd 表名 value1, value2 ...
    2. srem 表名 value1, value2 ...
    3. smembers 表名(获得全集)
    4. sismember 表名 value(判断value在不在s中)
    5. 集合运算 union、diff、inter...
    6. scard 表名 (获得该表的长度)

    有序集合(sorted-set)常用命令:
    实质上是一个类似TreeMap的东西,等价于TreeMap(value,score)且按score排序

    1. zadd 表名 score1 value1 score2 value2 score3 value3
    2. zscore 表名 value(获得该value的分数 )
    3. zcard 表名(获得该表的长度)

    redis的特性
    多数据库, 类似MYSQL的不同数据库, REDIS有0-15(共16个数据库),通过SELECT切换。
    支持事务, multi exec discard.

    redis持久化
    RDB:每过一段时间将数据写入硬盘
    AOF:一般用来记录日志,修改后就同步
    无持久化

    • 单节点redis和redis cluster不同点:
      • jediscluster不支持ping操作
      • jediscluster不能同时操作多个key(mset、mget)
      • jediscluster不支持flushall、flushdb操作

    单线程的Redis为什么这么快?

    • 纯内存操作
    • 单线程操作, 避免了频繁的上下文切换
    • 采用了非阻塞I/O多路复用机制
      • 传统并发模型: 每个I/O流都有一个新的线程管理
      • I/O多路复用: 单个线程, 通过跟踪每个I/O流的状态,管理多个I/O流

    REDIS的过期策略以及内存淘汰机制:定期删除+惰性删除策略

    • 定时删除(消耗资源大,到时间就一定要删除,可能此时正有请求),定期随机检查部分KEY并进行删除
    • 定期删除如果没有删除到,就会执行惰性删除(在获取某个Key的时候,Redis会检查这个Key是否设置了过期时间,如果过期了,此时就会删除)
    • 如果即没定期淘汰,也没访问,那么会导致内存越来越高。就应该采用内存淘汰机制(ALLKEYS-LRU 键空间中,移除最近最少使用的KEY)。

    四个常见问题:

    • 缓存和数据库双写一致性问题

      • ...
    • 缓存雪崩问题

      • 原因:缓存同一时间大面积失效,请求又都怼到了数据库上。
      • 解决方案:给缓存失效时间加个随机值, 互斥锁, 双缓存(?)
    • 缓存击穿问题

      • 原因:所有请求避开缓存,导致所有请求怼数据库
      • 解决:利用互斥锁(获得锁才能请求数据库), 异步更新机制(维护一个缓存失效时间,如果缓存过期了,异步起一个线程去读数据库,更新缓存),提供一个能迅速判断请求是否有效的拦截机制(?如果Key不合法,直接返回)
    • 缓存的并发竞争问题

      • 多个子系统Set 一个Key(如果不要求按顺序对Key操作, 使用分布式锁, 抢到锁就可以set)、(要求顺序,可以在VALUE上加上时间戳, 根据时间戳来进行时间操作)。
    • 一些常见操作

      • setnx(SET if Not eXist)
      • setex(set and expire) 设置值并且将key的生存时间设为seconds。
      • hdel(删除哈希表中的一个或多个指定域,不存在的域将被忽略) HDEL KEY field[field ...]
      • hmset (hash multi set)
      • hscan(hash iterator) hscan(key, cursor, match), cursor用于指定游标, match用于过滤结果。【cursor从0开始, 当cursor为0时结束。】
      • zrem(删除多个)。
    • jediscluster使用crc16哈希槽算法

    • 分布式session

      1. 考虑到使用集群来跑项目 , session难以共享。
      2. 使用redis模拟session。 cookie保存一个token, 然后通过这个token来确定一个用户在redis中的数据。(其中涉及到json序列化和反序列化)
    • jediscluster API 基本与 cmd client一致, 用个service或者util简单封装一下就好。

    • jedis和redistemplate:http://shift-alt-ctrl.iteye.com/blog/1886831

    • spring redistemplate

      • 内部操作的是jedis
      • redisTemplate.opsForValue();//操作字符串
      • redisTemplate.opsForHash();//操作hash
      • redisTemplate.opsForList();//操作list
      • redisTemplate.opsForSet();//操作set
      • redisTemplate.opsForZSet();//操作有序set
      • 通过4个序列化方法定义序列化方式(貌似不使用默认也不指定,是通过byte传输), 其它使用参考API。
    • redis分布式锁:

      1. 竞争资源抢占一个锁(一个String表示某个特定资源), 锁的有效时间(锁持续的时间),超时时间(获取锁失败后重试的时间)
      2. 加锁逻辑
      3. setnx, 如果成功则成功,否则
      4. get 判断锁是否超时, 超时的情况下 getset并且判断getset得到的值是否和之前一致(CAS的思想),如果是的话返回true,否则
      5. 不断尝试获得锁
      6. 解锁逻辑
      7. 如果当前时间 > 锁的到期时间 , 不做处理
      8. 否则删除key
    • redis pipeline:

      • redis 是一个基于TCP 的C/S 架构软件, 当客户端向服务端发送请求时, 需要消耗一定的时间用于往返传输数据。如果客户端需要服务端进行100次操作, 显然逐条发送会造成redis 空闲(处理速度大于操作到来的速度) 而 资源浪费。
      • 第一种方式是通过batch, 单条批量操作, multiset、multiget这样。
      • 第二种方式是通过pipeline, 思路一样, 只不过用在set上, 没法multi多个set,而pipeline是把指令作为流水线打过去。
    • redis lua:

      • 通过脚本实现CAS,防止出现并发问题(相当于全局串行了)

    相关文章

      网友评论

          本文标题:REDIS

          本文链接:https://www.haomeiwen.com/subject/cyrkeftx.html