zoukankan      html  css  js  c++  java
  • Redis


     一、什么是Redis?

    1.redis是一款高性能的NOSQL系列的非关系型数据库

    键值(Key-Value)存储数据库
    相关产品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
    典型应用: 内容缓存,主要用于处理大量数据的高访问负载。
    数据模型: 一系列键值对
    优势: 快速查询
    劣势: 存储的数据缺少结构化

    2.redis的应用场景

    • 缓存(数据查询、短连接、新闻内容、商品内容等等)
    • 聊天室的在线好友列表
    • 任务队列。(秒杀、抢购、12306等等)
    • 应用排行榜
    • 网站访问统计
    • 数据过期处理(可以精确到毫秒
    • 分布式集群架构中的session分离

    使用redis缓存一些不经常发生变化的数据。

    3.数据结构

    Redis是key/value键值对形式的数据库。key是字符串,value可以是以下五种类型

     

     value的数据结构:
    1) 字符串类型 string
    2) 哈希类型 hash : map格式
    3) 列表类型 list : linkedlist格式。支持重复元素
    4) 集合类型 set : 不允许重复元素
    5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序

     

    4.操作命令:

    https://www.redis.net.cn/tutorial/3517.html 

    命令操作
        1. redis的数据结构:
            * redis存储的是:key,value格式的数据,其中key都是字符串,value有5种不同的数据结构
                * value的数据结构:
                    1) 字符串类型 string
                    2) 哈希类型 hash : map格式  
                    3) 列表类型 list : linkedlist格式。支持重复元素
                    4) 集合类型 set  : 不允许重复元素
                    5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序
        
        2. 字符串类型 string
            1. 存储: set key value
                127.0.0.1:6379> set username zhangsan
                OK
            2. 获取: get key
                127.0.0.1:6379> get username
                "zhangsan"
            3. 删除: del key
                127.0.0.1:6379> del age
                (integer) 1
        3. 哈希类型 hash
            1. 存储: hset key field value
                127.0.0.1:6379> hset myhash username lisi
                (integer) 1
                127.0.0.1:6379> hset myhash password 123
                (integer) 1
            2. 获取: 
                * hget key field: 获取指定的field对应的值
                    127.0.0.1:6379> hget myhash username
                    "lisi"
                * hgetall key:获取所有的field和value
                    127.0.0.1:6379> hgetall myhash
                    1) "username"
                    2) "lisi"
                    3) "password"
                    4) "123"
                    
            3. 删除: hdel key field
                127.0.0.1:6379> hdel myhash username
                (integer) 1
        
        4. 列表类型 list:可以添加一个元素到列表的头部(左边)或者尾部(右边)
            1. 添加:
                1. lpush key value: 将元素加入列表左表
                    
                2. rpush key value:将元素加入列表右边
                    
                    127.0.0.1:6379> lpush myList a
                    (integer) 1
                    127.0.0.1:6379> lpush myList b
                    (integer) 2
                    127.0.0.1:6379> rpush myList c
                    (integer) 3
            2. 获取:
                * lrange key start end :范围获取
                    127.0.0.1:6379> lrange myList 0 -1
                    1) "b"
                    2) "a"
                    3) "c"
            3. 删除:
                * lpop key: 删除列表最左边的元素,并将元素返回
                * rpop key: 删除列表最右边的元素,并将元素返回
    5. 集合类型 set : 不允许重复元素
            1. 存储:sadd key value
                127.0.0.1:6379> sadd myset a
                (integer) 1
                127.0.0.1:6379> sadd myset a
                (integer) 0
            2. 获取:smembers key:获取set集合中所有元素
                127.0.0.1:6379> smembers myset
                1) "a"
            3. 删除:srem key value:删除set集合中的某个元素    
                127.0.0.1:6379> srem myset a
                (integer) 1
        6. 有序集合类型 sortedset:不允许重复元素,且元素有顺序.每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
    
            1. 存储:zadd key score value
                127.0.0.1:6379> zadd mysort 60 zhangsan
                (integer) 1
                127.0.0.1:6379> zadd mysort 50 lisi
                (integer) 1
                127.0.0.1:6379> zadd mysort 80 wangwu
                (integer) 1
            2. 获取:zrange key start end [withscores]
                127.0.0.1:6379> zrange mysort 0 -1
                1) "lisi"
                2) "zhangsan"
                3) "wangwu"
    
                127.0.0.1:6379> zrange mysort 0 -1 withscores
                1) "zhangsan"
                2) "60"
                3) "wangwu"
                4) "80"
                5) "lisi"
                6) "500"
            3. 删除:zrem key value
                127.0.0.1:6379> zrem mysort lisi
                (integer) 1
    
        7. 通用命令
            1. keys * : 查询所有的键
            2. type key : 获取键对应的value的类型
            3. del key:删除指定的key value

    二、NOSQL和关系型数据库(MySql)比较

    1.查询速度:nosql数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘中,自然查询速度远不及nosql数据库。

    2.存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式,而数据库则只支持基础类型。

    非关系型数据库的优势:
    1)性能NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。
    2)可扩展性同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。

    关系型数据库的优势:
    1)复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
    2)事务支持使得对于安全性能很高的数据访问要求得以实现。对于这两类数据库,对方的优势就是自己的弱势,反之亦然。

    三、持久化

    1. redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
    2. redis持久化机制:

    • RDB(redis database):默认方式,不需要进行配置,默认就使用这种机制

                  * 在一定的间隔时间中,检测key的变化情况,然后持久化数据

                   1. 编辑redis.windows.conf文件

                    

                      参数解释

    #after 900 sec (15 min) if at least 1 key changed 15分钟有一个键变化就进行持久化
    save 900 1
    #after 300 sec (5 min) if at least 10 keys changed 5分钟有10个键变化就进行持久化
    save 300 10

    #after 60 sec if at least 10000 keys changed

    save 60 10000

    1分钟有1000个键变化就进行持久化

                     当发生持久化后,就会在dump.rdb文件

    • AOF(append only file)
          日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据

    RDB优点:
    1 适合大规模的数据恢复。
    2 如果业务对数据完整性和一致性要求不高,RDB是很好的选择。
    缺点:
    1 数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
    2 备份时占用内存

    Redis 针对 AOF文件大的问题,提供重写的瘦身机制。

    四、Redis缓存相关问题

    1.缓存穿透

    2.缓存雪崩

    3.缓存击穿

    1.缓存穿透
    缓存穿透是指查询一个数据库一定不存在的数据。
    例如我们的数据表中主键是自增产生的,所有的主键值都大于0。此时如果用户传入的参数为-1,会是怎么样?这个-1,就是一定不存在的对象。程序就会每次都去查询数据库,而每次查询都是空,每次又都不会进行缓存。假如有人恶意攻击,就可以利用这个漏洞,对数据库造成压力,甚至压垮我们的数据库。
    为了防止有人利用这个漏洞恶意攻击我们的数据库,我们可以采取如下措施:
    如果从数据库查询的对象为空,也放入缓存,key为用户提交过来的主键值,value为null,只是设定的缓存过期时间较短,比如设置为60秒。这样下次用户再根据这个key查询redis缓存就可以查询到值了(当然值为null),从而保护我们的数据库免遭攻击。
     
    2.缓存雪崩
    缓存雪崩,是指在某一个时间段,缓存集中过期失效。在缓存集中失效的这个时间段对数据的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰。
    为了避免缓存雪崩的发生,我们可以将缓存的数据设置不同的失效时间,这样就可以避免缓存数据在某个时间段集中失效。例如对于热门的数据(访问频率高的数据)可以缓存的时间长一些,对于冷门的数据可以缓存的时间段一些。甚至对于一些特别热门的数据可以设置永不过期。
     
    3.缓存击穿
    缓存击穿,是指一个key非常热点(例如双十一期间进行抢购的商品数据),在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求到数据
    库上,就像在一个屏障上凿开了一个洞。我们同样可以将这些热点数据设置永不过期就可以解决缓存击穿的问题了

    五、Redis集群方案

    1.解决问题
    单台Redis服务性能不足的问题。这就需要使用到Redis的集群了。Redis集群有多种方案,下面分别进行讲解。
    2.主从复制Replication
    redis支持主从复制的模式。
    在主从复制模式下Redis节点分为两种角色:主节点(也称为master)和从节点(也称为slave)。这种模式集群是由一个主节点和多个从节点构成。
    原则:Master会将数据同步到slave,而slave不会将数据同步到master。Slave启动时会连接master来同步数据

     这是一个典型的分布式读写分离模型。我们可以利用master来处理写操作,slave提供读操作。这样可以有效减少单个机器的并发访问数量。 

    现在我们就可以通过这种方式配置多个从节点进行读操作,主节点进行写操作,实现读写分离
    3.哨兵sentinel
    我们现在已经给Redis实现了主从复制,可将主节点数据同步给从节点,实现了读写分离,提高Redis的性能。但是现在还存在一个问题,就是在主从复制这种模式下只有一个主节点,一旦主节点宕机,就无
    法再进行写操作了。也就是说主从复制这种模式没有实现高可用。
     
    那么什么是高可用呢?
    高可用(HA)是分布式系统架构设计中必须考虑的因素之一,它是通过架构设计减少系统不能提供服务的时间。保证高可用通常遵循下面几点:
    1. 单点是系统高可用的大敌,应该尽量在系统设计的过程中避免单点。
    2. 通过架构设计而保证系统高可用的,其核心准则是:冗余。
    3.
    实现自动故障转移
     
    如何实现高可用呢
    sentinel(哨兵)是用于监控redis集群中Master状态的工具,其本身也是一个独立运行的进程,是Redis的高可用解决方案,sentinel哨兵模式已经被集成在redis2.4之后的版本中。sentinel可以监视一个或者多个redis master服务,以及这些master服务的所有从服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求,并且其余从节点开始从新的主节点复制数据 

     

    4.Redis内置集群cluster 
    Redis ClusterRedis的内置集群,在Redis3.0推出的实现方案。在Redis3.0之前是没有这个内置集群的。Redis Cluster是无中心节点的集群架构,依靠Gossip协议协同自动化修复集群的状态。Redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。 
    Redis cluster集群架构图如下:
     
     
     
     
     
     
     
     
  • 相关阅读:
    python面向对象
    Python基本数据类型
    小刘同学的第一百四十四篇博文
    小刘同学的第一百四十三篇日记
    小刘同学的第一百四十二篇日记
    小刘同学的第一百四十一篇日记
    小刘同学的第一百四十篇日记
    小刘同学的第一百三十九篇博文
    小刘同学的第一百三十八篇日记
    小刘同学的第一百三十七篇日记
  • 原文地址:https://www.cnblogs.com/aaaazzzz/p/12790159.html
Copyright © 2011-2022 走看看