zoukankan      html  css  js  c++  java
  • Redis基础总结

    本文仅针对对Redis不熟悉的开发人员做入门培训。

    官方网站 https://redis.io/

    1、Redis是什么?

        Redis 是一个基于内存的高性能key-value数据库,全称是 (Remote Dictionary Server,远程字典服务)。

    2、Redis有什么特点?

    • 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
    • 支持丰富的数据类型
    • 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
    • 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
    • 缺点 是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写

    3、Redis的数据类型以及相关的一些基础语法。

            基础数据类型如下图所示

            粘贴图片 

        string 

            作为最简单的类型,基本用法其实很多,下面简单介绍几种常见用法     

    • 单值缓存
    Set key value
    Get key
    GetSet key value
     进行一些简单的数据缓存
    • 对象缓存
    Set user:1 jsonvalue
    Mset user:1:name 张三 user:1:age 18
    Mget user:1:name user:1:age
    进行一些常用的对象缓存,在一些情况下会比hash更高效
    • 简易分布式锁
    Setnx loclk:1 true (如果没有这个key会返回1,并且添加这个key,否则返回0)
    Del lock:1
    这种分为两步,1设置锁、2删除锁。存在一定的风险,比如设置了锁,但是删除出现异常,会导致程序死锁。
    建议使用下面这种语句实现简单的锁
    Set lock:1 true ex 10 nx(这个命令可以有效防止程序异常终止导致的死锁)
    • 计数器
    Incr article:readCount:1 //Incrby article:readCount:1 100
    适用场景:文章的阅读数,网站的被访问次数,订单编号的生成(高并发情况下一次取多个,
    放到程序内部慢慢消化)等
    Decr article:readCount:1 //Decrby article:readCount:1 100
    适用场景:登录异常次数限制(设置账号或者ip为key,设值为登陆次数,每次登陆失败执行此操作,
    当返回值小于0时,限制该账号或者ip调用登录接口)
    Get article:readCount:1
    
    • 设置过期
    expire key 10 (默认时间单位为秒)

     

        hash

            作为比较常用的类型,基本用法其实很多,下面简单介绍几种常见用法 

    • 基操
    HSet Key fielId value //插入一条hash记录 HSet sc:10086 1 1 (新增返回1,修改返回0)
    HIncrby Key fielId value //增加数量 Hincrby sc:10086 1 10(返回增加之后的数值)
    HLen Key fielId //获取总数 Hlen sc:10086(返回的是hash的行数)
    HDel key fielId //删除hash的一个key HDel sc:10086
    HGetall key //获取hash内部的所有值 HGetall sc:10086

    优点:

    1. 同类 数据归类整合存储,方便数据管理
    2. 相对于string操作更低的消耗内存与cpu
    3. 相对于string存储更节省空间

    缺点:

    1. 无 法针对fielId设置过期时间,只能针对key进行设置
    2. Redis集群架构下不适合大规模使用,因为无法进行数据分片存储,会导致数据过于集中,从而导致单节点压力过大

     

        list

            可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。

    内部实现是一个双向链表,两端的查找时间复杂度为0(1),具有两端读取添加速度极快的特点。

    • 基操
     LPush Key value //将一条记录推入表头(最左侧) LPush ListA 1 (返回列表的长度)
     RPush Key value //将一条记录推入表尾(最右侧) RPush ListA 1 (返回列表的长度)
     LPop key  //移除并返回列表的头元素  LPop ListA 
     RPop key //移除并返回列表的尾元素   RPop ListA 
     LRange key start stop  //返回指定区域中的元素,区间以偏移量制定 LRange ListA  2  5
     BLPop key [key] timeout //在表头弹出一个元素,如果没有的话则阻塞等待timeout秒,
    		         若timeout=0,一直阻塞 BLPop ListA 99 10
     BRPop key [key] timeout //在表尾弹出一个元素,如果没有的话则阻塞等待timeout秒,
    		         若timeout=0,一直阻塞 BRPop ListA 99 10
    作用:构建常用的数据结构
          Stack(栈) = LPush + LPop
          Queue(队列) = LPush + RPop
          Blocking MQ(阻塞队列) = LPush + BRPop
    
    应用场景:消息流(将用户的通知消息的主键存入list,用户登陆之后推送给用户,而不是去数据库进行查找)

        set

            集合类型, 数据不重复且无序 ,内部实现是一个 散列表, 所以集合中的元素增删等操作时间复杂度均为0(1),常见的操作为交集、并集、差集的运算。

    • 基操
     SAdd key member //往集合中存入元素,元素存在就忽略,key不存在就创建 SAdd Students Tom
     SRem key member //集合中删除元素 SRem Students Tom
     SMembers key  //返回集合的所有元素  SMembers Students 
     SCARD key //获取集合中的元素个数   SCARD Students 
     SisMember key member  //判断元素是否存在于集合中 SisMember Students jack
    适用场景:用户的好友列表、关注列表、系统黑名单、Tag系统、文章的收藏列表等
     SRandmember key count //在集合key中选出count个元素 SRandmember Students 1
     Spop key count  //在集合key中选出count个元素并删除它 SPop Students 1
    适用场景:抽奖机制,随机排班等
    • 运算操作
    SInter key key key …… //求交集 SInter class1 class2 class3
     SInterStore newKey key key key …… 
    //把交集结果存入newKey中 SInterStore  class1-2-3 class1 class2 class3
     SUnion key key key …… //求并集 SUnion class1 class2 class3
     SUnionStore newKey key key key …… 
    //把并集结果存入newKey中 SUnionStore  class1-2-3 class1 class2 class3
     SDiff key key key …… //求差集 SDiff class1 class2 class3
     SDiffStore newKey key key key …… 
    //把差集结果存入newKey中 SDiffStore  class1-2-3 class1 class2 class3
    适用场景:共同好友模型(Sinter)
    可能认识的人模型 (SDiff)
    共同关注模型 (SUnion )

     

        Zset

            有序集合类型, 数据不重复且有序 ,为集合中的每个元素都关联了一个分数。

    • 基操

    基本上具有list和set的基操集合

    适用场景:
    时间轴(使用时间作为score)
    积分排行榜(积分作为score)
    消息队列(具有优先级以及权重的特点)

        Geo

            其实也是一种有序集合类型, 数据不重复且有序 ,这里关联的分数是程序通过某种算法对经纬度进行计算  得出的。

    • 基操
     GeoAdd key log lat member //存入一个地理信息,key不存在就创建 geoadd city 109.89 78.11 上海
     Geopos key member //返回指定元素的位置 Geopos city 上海
     GeoDist key member1 member2 [unit]  //返回两个地点之间的距离 有一个地点不存在就返回空值 
                       //GeoDist city 上海 北京 km
    				util单位: m表示单位为米
    	                  km表示单位为千米 
                          mi表示单位为英里
    	                  ft表示单位为英尺
     GeoRadius key longitude latitude radius m|km|ft|mi [withcoord][withdist][withhash][asc|desc]
    [count count] 
    //以给定的经纬度为中心,返回键包含的位置元素当中,与中心的距离不超过给定最大距离的所有位置元素。
    使用场景:
    附近的人(陌陌、微信)
    地理信息相关的操作场景,比如 计算两点之间的距离,或者某个地点周围多少距离的所有地点集合等

     

        HyperL ogLog

            适用场景应该是和 布隆过滤器有关, 涉及到的是缓存穿透的解决方案相关知识,不做赘述 。

    3.1、list和Zset的对比

    相同点:

    1. 都是有序的
    2. 都可以获取某一个范围内的元素

    不同点:

    1. 列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。
    2. 有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快。 列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现)
    3. 有序集合要比列表类型耗更多的内存

    4、一些常见的概念介绍

    • 缓存预热
    缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,
    先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
    • 缓存雪崩
    由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的
    缓存过期),所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造
    成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。
    • 缓存穿透
    指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次
    都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)
    • 缓存击穿
    对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数
    据。这个时候,需要考虑一个问题:缓存被“击穿”的问题,这个和缓存雪崩的区别在于这里针对某一key缓存
    ,前者则是很多key。
    

    5、是否有必要使用redis做缓存?

    粘贴图片

  • 相关阅读:
    springsecurity 注解开发
    springsecurity 授权
    【ElasticSearch】集群搭建
    【CentOS7.9】防火墙配置使用
    【CentOS7.9】创建及挂载共享文件夹
    查看Linux发行版
    【Spring Cloud】spring-cloud2020和spring-cloud-alibaba2021问题记录
    【Spring Cloud】spring.factories
    三剑客-----grep
    git安装
  • 原文地址:https://www.cnblogs.com/yuchenghao/p/12102574.html
Copyright © 2011-2022 走看看