zoukankan      html  css  js  c++  java
  • Redis 及其分布式应用场景

    转自:

    https://zhuanlan.zhihu.com/p/126344521

    Redis概况

    Redis(Remote Dictionary Server,即远程字典服务),是一个开源的(BSD 许可的)内存中的数据结构存储器,用作数据库、缓存和消息代理。它支持丰富的数据结构(如字符串、哈希、列表、集、带范围查询的排序集、位图、超日志、具有半径查询和流的地理空间索引)。Redis 具有内置复制、Lua 脚本、LRU eviction、事务和不同级别的磁盘持久性,并通过 Redis Sentinel 提供高可用性,并通过 Redis 群集自动分区。

    从2010年3月15日起,Redis的开发工作由VMware主持;从2013年5月开始,Redis的开发由Pivotal赞助。

    Redis 主要内容:

    • 性能:数据在内存中(避免了磁盘IO的成本),读写速度非常快,支持并发 10W QPS;
    • 进程、线程模型:单进程单线程,是线程安全的,采用 IO 多路复用机制模型(同步非阻塞)。
    • 丰富的数据结构:String字符串、Hash哈希映射、List列表、Set集合、ZSet带范围查询的排序集合、bitmap位图、hyperloglog超日志、具有半径查询和流的地理空间索引;
    • 数据持久化机制:可以将内存中数据保存在磁盘中,重启时加载;
    • 高可用集群架构:通过 Redis Sentinel 提供高可用性,并通过 Redis 群集自动分区。(主从复制、哨兵架构);
    • 分布式应用场景:用作缓存;可用作消息中间件,支持发布订阅;用作分布式锁(redis的并发竞争key机制)等等;

    核心数据结构-操作命令-应用场景

    #macos简单安装redis
    brew install redis
    #配置文件
    vim /usr/local/etc/redis.conf
    #启动服务
    redis-server
    
    #进入客户端
    redis-cli -p 127.0.0.1 -p 6379
    #后续执行操作命令即可
    127.0.0.1:6379> set owner Yoland
    OK
    127.0.0.1:6379> get owner
    "Yoland"
    127.0.0.1:6379> exists owner
    (integer) 1
    127.0.0.1:6379> type onwer
    String
    127.0.0.1:6379> del owner
    (integer) 1
    127.0.0.1:6379> exists owner
    (integer) 0
    
    # 设置过期时间
    127.0.0.1:6379> expire key timeout(单位为秒)
    • 实现分布式锁:

    1.获取锁的时候,使用 setnx(SETNX key val:当且仅当 key 不存在时,set 一个 key 为 val 的字符串,返回 1;若 key 存在,则什么都不做,返回 0)加锁,锁的 value 值为一个随机生成的 UUID,在释放锁的时候进行判断。并使用 expire 命令为锁添加一个超时时间,超过该时间则自动释放锁。

    2. 获取锁的时候调用 setnx,如果返回 0,则该锁正在被别人使用,返回 1 则成功获取 锁。 还设置一个获取的超时时间,若超过这个时间则放弃获取锁。

    3. 释放锁的时候,通过 UUID 判断是不是该锁,若是该锁,则执行 delete 进行锁释放。

    • 事务操作

    Redis事务可以一次执行多个命令,事务具有以下特征

    • 隔离操作:事务中的所有命令都会序列化、按顺序地执行,不会被其他命令打扰。
    • 原子操作:事务中的命令要么全部被执行,要么全部都不执行
    • 开启一个事务
    multi
    以后执行的所有命令,都在这个事务中执行的。
    
    执行事务
    1exec
      会将在multi和exec中的操作一并提交。
    
    取消事务
    1discard
      会将multi后的所有命令取消。
    
    监视一个或者多个key
    watch key...
      监视一个(或多个)key,如果在事务执行之前这个(或这些) key被其他命令所改动,那么事务将被打断。
    
    取消所有key的监视
    unwatch 
    • 发布/订阅操作
    给某个频道发布消息
    publish channel message
    订阅某个频道的消息
    subscribe channel 

     

    key-String

    String 是 Redis 最基本的类型,可以理解成与 Memcached 一模一样的类型;

    • 一个 Key 对应一个 Value, value是一个整体;
    • Value 可以是任何类型数据(因为String 类型是二进制安全的:意思是 String 类型可以包含任何数据,如:String、数字、 jpg 图片、序列化的对象);
    • Value最大能存储 512M;

    操作命令:

    #S听类型 对字符串的支持
    > SET mykey somevalue
    OK
    > GET mykey
    "somevalue"
    
    #String类型 对数字的支持
    > set counter 100
    OK
    > incr counter
    (integer) 101
    > incr counter
    (integer) 102
    > incrby counter 50
    (integer) 152
    
    # 设置多数据
    > mset a 10 b 20 c 30
    OK
    > mget a b c
    1) "10"
    2) "20"
    3) "30"
    > mget a
    1) "10"

    应用场景:

    • 单值缓存;
    SET key value
    GET key
    • 对象缓存(json格式,但不如使用hash更灵活):
    #使用String缓存对象
    SET user:1 value(json格式数据)
    GET user:1 
    #使用Hash缓存对象
    MSET user:1:name yuan user:1:age 18
    MGET user:1:name user:1:age 

    key-Hash

    Hash是一个键值(key-value)的集合。

    • 一个key对应一个Hash(key-value entry 的集合);
    • 适合存储对象:

    操作命令:HMSet、HGet、HGetAll、HLen、HDel、hincrby

    //todo

    应用场景:适合存储对象,对象的每个属性和值,可以用hash的key-value来存储;虽然对象也可以通过json存储到String值中,但是使用Hash更方便操作对象的某个属性;

     

    key-List

    • List 列表是简单的字符串列表,按照插入顺序排序。
    • 数据结构:List 就是链表,可以用来当消息队列用。Redis 提供了 List 的 Push 和 Pop 操作,还提供了操作某一段的 API,可以直接查询或者删除某一段的元素。
    • 实现方式:Redis 的 List 的是实现是一个双向链表,既可以支持反向查找和遍历,更方便操作,不过带来了额外的内存开销。

    操作命令:可以添加一个元素到列表的头部(左边)或者尾部(右边) 常用命令:插入lpush/rpush、查询lpop/rpop、范围查询lrange(获取列表片段)、阻塞查询BLPop/BRPop(list空时阻塞)、删除LDrop/RDrop等。

    //todo

    应用场景:List 应用场景非常多,也是 Redis 最重要的数据结构之一,比如 :

    • 微博、Twitter 的关注列表、粉丝列表都可以用 List 结构来实现。
    • 公众号、微博的新消息列表, 使用:LRange key start end;

     

    key-Set

    • Set 是 String 类型的无序集合(集合即元素唯一)。Set 中的元素是无序的,而且是不重复的。
    • Set 是通过 hashtable 实现的;

    操作命令:SADDSCARDSDIFFSDIFFSTORESINTERSINTERSTORESISMEMBERSMEMBERSSMOVESPOPSRANDMEMBERSREMSSCANSUNIONSUNIONSTORE

    #添加集合中的成员
    > sadd myset 1 2 3
    (integer) 3
    #查看集合中的成员
    > smembers myset
    1. 3
    2. 1
    3. 2
    #成员是否属于集合
    > sismember myset 3
    (integer) 1
    > sismember myset 30
    (integer) 0
    #集合操作
    #交集
    SINTER set1 set2
    #并集 set1 + set2
    SUNION set1 set2
    #差集 set1-(set2+set3)
    SDIFF set1 set2 set3

    应用场景:Redis 的 Set 对外提供的功能和 List 一样是一个列表,特殊之处在于 Set 是自动去重的,而且 Set 提供了判断某个成员是否在一个 Set 集合中。

    • 微信抽奖小程序
    redis> SADD myset one two three
    (integer) 3
    # 从集合中随机获取n个成员
    redis> SRANDMEMBER myset
    "two"
    redis> SRANDMEMBER myset 2
    1) "one"
    2) "three"
    redis> SRANDMEMBER myset -5
    1) "two"
    2) "three"
    3) "two"
    4) "three"
    5) "one"
    
    # 从集合中随机获取n个成员,同时将取出的成员从集合中删除
    
    • 微信/微博的点赞、收藏、标签,用:
    SREM
    SISMEMBER
    SMEMBER
    SCARD

    • 实现微博、微信的关注模型:
    #共同关注(关注某明星的粉丝也关注的其他明星)
    
    #我关注的人也关注的明星
    
    #推荐关注/可能认识的人(我的好友关注了,而我没有关注的人)
    

    key-ZSet

    Zset 和 Set 一样是 String 类型元素的集合,且不允许重复的元素,但是它时排序的( Sorted Set 结构)。

    • 和 Set 相比,Sorted Set关联了一个 Double 类型权重的参数 Score,使得集合中的元素能够按照 Score 进行有序排列,Redis 正是通过分数来为集合中的成员进行从小到大的排序。
    • 实现方式:Redis Sorted Set 的内部使用 HashMap 和跳跃表(skipList)来保证数据的存储和有序,HashMap 里放的是成员到 Score 的映射。 而跳跃表里存放的是所有的成员,排序依据是 HashMap 里存的 Score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

    常用命令:zadd、zrange、zrem、zcard 等。

    使用场景:ZSet 可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。

    • 排行榜/热度榜
    • 带优先级(权重)的消息队列

     

    Redis高可用、分布式集群架构(千万级)

    (待续)

    SpringBoot 用 redis 作缓存

    Spring Boot 使用的。一般有两种方式,一种是直接通过 RedisTemplate 来使用,另一种是使用 Spring Cache 集成 Redis(也就是注解的方式)。

    (待续)

  • 相关阅读:
    Oracle—SQL基础语句
    ORACLE中数据类型
    ORACLE表结构的操作
    PLSQL--存储过程
    PLSQL--游标
    PLSQL --流程控制
    PLSQL --变量
    Ajax请求校验username是否可用
    jQuery学习笔记(四)使用选择器三
    jQuery学习笔记(三)使用选择器二
  • 原文地址:https://www.cnblogs.com/heyanan/p/12799892.html
Copyright © 2011-2022 走看看