zoukankan      html  css  js  c++  java
  • 数据库--Redis

    原因: 源码是官方configure过的,但官方configure时,生成的文件有时间戳信息,所以如果你的虚拟机的时间不对,比如说是2022年,就可能会出错
    解决: date -s ‘yyyy-mm-dd hh:mm:ss’ 重写时间
    再 clock -w 写入cmos
    

      

    1 redis 介绍

    redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步

    1.1 redis 特性

     
    (1) 读写性能优异,因为数据存在内存中,类似于HashMap,时间复杂度都是O(1)
    (2) 支持丰富数据类型,支持string,list,set,sorted set,hash
    (3) 单线程,支持事务,操作都是原子性,对数据的更改要么全部执行,要么全部不执行
    (4) 数据自动过期
    (5)Redis支持数据的备份,即master-slave模式的数据备份。
    (6)dis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
    (7) 分布式
    

      

    1.2 Memcache与Redis的区别都有哪些?

     
    1)、存储方式
    Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。
    Redis有部份存在硬盘上,这样能保证数据的持久性。
    2)、数据支持类型
    Memcache对数据类型支持相对简单。
    Redis有复杂的数据类型。
    
    3),value大小
    redis最大可以达到1GB,而memcache只有1MB
    

     

    2 redis 的应用场景

     

    (1) 会话缓存(重点session cache)

     
    缓存是Redis最常见的应用场景 Redis内部是支持事务的,在使用时候能有效保证数据的一致性。 作为缓存使用时,一般有两种方式保存数据:
    1、读取前,先去读Redis,如果没有数据,读取数据库,将数据拉入Redis。
    2、插入数据时,同时写入Redis。
    方案一:实施起来简单,但是有两个需要注意的地方:
    1、避免缓存击穿。(数据库没有就需要命中的数据,导致Redis一直没有数据,而一直命中数据库。)
    2、数据的实时性相对会差一点。
    方案二:数据实时性强,但是开发时不便于统一处理。 。
    当然,两种方式根据实际情况来适用。如:方案一适用于对于数据实时性要求不是特别高的场景。方案二适用于字典表、数据量不大的数据存储。
    

      

     

    (2) 消息队列(重点)

     
    Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。
    Celery有一个后台就是使用Redis作为broker
    

      

    (3) 频率控制(重点)

     
    对用户登录次数进行限制  比如登录三次失败后就5分钟之后再去登录
    运用redis中的incr  当验证的用户名和密码是错误时 就incr依次加一  然后在设置一个过期时间
    

      

    import redis
    
    r = redis.Redis()
    print(r.incr(10086))   # 结果是依次加1的 
    

      

    (4) 排行榜 计数器 (重点)

     

    Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构

    比如点击量 播放量等

    (5) 全页缓存

    (6) 发布订阅功能

    3 redis 操作

     

    具体详细操作 https://www.runoob.com/redis/redis-strings.html

    连接本地redis

    终端中  redis-cli
    

      

    3.1 String操作

     

    set get incr 重点

    String操作,redis中的String在在内存中按照一个name对应一个value来存储。如图:

    1 set key value 设置指定 key 的值

     
    set name owen  
    

      

    2 get key 获取指定 key 的值

     
    get name   # "owen"
    

     

    3 getrange key start end 截取得到的子字符串。

     
    首先,设置 mykey 的值并截取字符串。
    redis 127.0.0.1:6379> SET mykey "This is my test key"
    OK
    redis 127.0.0.1:6379> GETRANGE mykey 0 3
    // "This" 空格也算
    redis 127.0.0.1:6379> GETRANGE mykey 0 -1  # 
    // "This is my test key"
    

      

    4 getset key value getset 命令用于设置指定 key 的值,并返回 key 的旧值。

    **4  getset key value**    getset 命令用于设置指定 key 的值,并返回 key 的旧值。
    
    ```
    返回给定 key 的旧值。 当 key 没有旧值时,即 key 不存在时,返回 nil 。 
    当 key 存在但不是字符串类型时,返回一个错误。
    ```
    

      

    redis> GETSET db mongodb    # 没有旧值,返回 nil
    (nil)
    
    redis> GET db
    "mongodb"
    
    redis> GETSET db redis      # 返回旧值 mongodb
    "mongodb"
    
    redis> GET db
    "redis"
    

      

    这里就举证几个例子 其他操作看官网

    4 redis 事务 (重要)

     
    Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
    Redis事务的主要作用就是串联多个命令防止别的命令插队
    

      

    Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
    
    - 批量操作在发送 EXEC 命令前被放入队列缓存。 
    
    - 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
    
    -  在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
    
    一个事务从开始到执行会经历以下三个阶段: 
    
    -  开始事务。
    -  命令入队。
    -  执行事务。
    

      

    事务命令

     

    序号命令及描述
    1 DISCARD 取消事务,放弃执行事务块内的所有命令。
    2 EXEC 执行所有事务块内的命令。
    3 MULTI 标记一个事务块的开始。
    4 UNWATCH 取消 WATCH 命令对所有 key 的监视。
    5 [WATCH key key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

     

     

    5 redis 安装与使用

     

    1 linux下安装

    参考博客 https://www.cnblogs.com/wangyong123/p/11625050.html

    1.1 安装

    1、官方站点: redis.io 下载最新版或者最新stable版
    2、解压源码并进入目录
    3、不用configure
    4、直接make
    5、可选步骤: make test 测试编译情况
    (可能出现: need tcl >8.4这种情况, yum install tcl)
    6、安装到指定的目录,比如 /usr/local/redis
    make  PREFIX=/usr/local/redis install
    注: PREFIX要大写
    7:make install之后, 得到如下几个文件
    redis-benchmark 性能测试工具
    redis-check-aof 日志文件检测工(比如断电造成日志损坏,可以检测并修复)
    redis-check-dump 快照文件检测工具,效果类上
    redis-cli 客户端
    redis-server 服务端
    8、复制配置文件
    Cp /path/redis.conf /usr/local/redis
    

     

    1.2启动

     
    path/to/redis/bin/redis-server  ./path/to/conf-file
    例:[root@localhost redis]# ./bin/redis-server ./redis.conf
    

      

    1.3连接

     
    #/path/to/redis/bin/redis-cli [-h localhost -p 6379 ]
    

      

    1.4 让redis以后台进程的形式运行

     
    编辑conf配置文件,修改如下内容;
    daemonize yes
    

      

    1.5 易出现的问题 时间错误

     
    原因: 源码是官方configure过的,但官方configure时,生成的文件有时间戳信息,所以如果你的虚拟机的时间不对,比如说是2022年,就可能会出错
    解决: date -s ‘yyyy-mm-dd hh:mm:ss’ 重写时间
    再 clock -w 写入cmos
    

     

    2 window下安装

    参考博客:https://www.cnblogs.com/liuqingzheng/p/9831331.html

     

     

    6 python操作redis (重点)

    安装redis模块

     
    pip  install redis
    

      

    普通连接

     
    import redis
    
    r = redis.Redis(host='127.0.0.1', port=6379)
    r.set('foo', 'Bar')
    print(r.get('foo'))
    

      

    连接池连接

     
      redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池
    

      

    import redis
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)
    r = redis.Redis(connection_pool=pool)
    r.set('foo', 'Bar')
    print(r.get('foo'))
    

      

     

    7 Django使用redis

    方式一

    安装django-redis模块
    pip install django-redis
    

      

    # setting里的配置 
    # redis配置
    
    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "CONNECTION_POOL_KWARGS": {"max_connections": 100}
                # "PASSWORD": "123",
            }
        }
    }
    

      

     

    视图函数

     
    from django_redis import get_redis_connection
    conn = get_redis_connection('default')
    print(conn.hgetall('xxx'))
    

      

    方式二

    utils文件夹下,建立redis_pool.py

    import redis
    POOL = redis.ConnectionPool(host='127.0.0.1', port=6379,password='1234',max_connections=1000)
    

      

    视图函数

     
    import redis
    from django.shortcuts import render,HttpResponse
    from utils.redis_pool import POOL
    
    def index(request):
        conn = redis.Redis(connection_pool=POOL)
        conn.hset('kkk','age',18)
    
        return HttpResponse('设置成功')
    def order(request):
        conn = redis.Redis(connection_pool=POOL)
        conn.hget('kkk','age')
    
        return HttpResponse('获取成功')
    

      

    8 Redis 持久化存储方案

    Redis目前提供了两种方式的持久化机制[其实还有VM、DISKSTORE,但是官方不推荐]:

    • ①RDB持久化机制:将Redis在内存中的数据,定时的写入到磁盘上

    • ②AOF持久化机制:将操作日志aof文件通过追加的方式写入文件 官网链接:https://redis.io/topics/persistence

     

    一:RDB

    RDB中文名为快照-内存,它的持久化实现原理就是通过开启RDB[默认方案]并配置时间周期定时将数据从内存写入硬盘。

    Redis提供如下几种方式来对数据进行快照:

    • 在redis.conf中配置

    • 执行save或bgsave

    • 执行flushall

    • 执行主从复制

    下图将描述Redis如何实现持久化:

     

     RDB的持久化是一个全量保存数据过程,若数据量较大,则保存时间就会有点长。此时,当在快照的时候进行写操作,那么势必出现数据不一致情况。因而Redis采取的是Copy-on-Write方案,来保证在快照中的数据是不会有变化的。该方案中快照数据是fork一个子进程来处理内存中数据写入硬盘。图中可以看到子进程是先保存一个临时的RDB文件,这样好处是当服务端崩溃时,只有上次快照中有新增或变化的数据异常,绝大部分数据仍然是正常的。Redis存储的数据默认保存在与redis-conf同一级目录,名称为dump.rdb。如果想要将数据放在自定义的路径下、自定义名称就修改如下配置即可。

    # Note that you must specify a directory here, not a file name.dir./ # The filename where to dump the DBdbfilename dump.rdb修改快照周期,一行一个配置,各配置之间是或的关系: # 周期性执行条件的设置格式为

    • save # 默认配置

    • save 900 1 //表示900秒中至少1个建被修改就保存

    • save 300 10 //表示300秒中至少10个建被修改就保存

    • save 60 10000# 以下设置方式为关闭RDB快照功能,默认是注释掉的save""

    二:AOF

    为满足Redis异常崩溃导致少量数据丢失,或快照方式存储数据时间较长、占用CPU资源较高,Redis提供增量更新数据的AOF持久化方案。

    AOF持久化,其原理是通过日志的形式记录服务器处理的每一个写、删除、更新操作,这样可以方便查看。当RDB与AOF都开启时,将使用AOF。下图简要描述AOF执行过程:

     

    Redis在处理一条命令时,并不立即调用write写AOF文件,只是将数据写入到AOF buffer(server.aof_buf)中。调用write和命令处理是分开的,Redis只在每次进入epoll_wait之前做write操作。如何配置AOF:

    # 将no改为yes即可开启appendonlyno# AOF记录日志名称,保存在bin下appendfilename"appendonly.aof"# 同步策略,有everysec、always、no,默认是everysec每秒同步;# always表示有写操作就执行调用fsync(Linux为调用fdatasync);# no表示写入后不会有fsync调用,由操作系统自动调度刷磁盘,性能是最好的appendfsync everysec

     

    三:总结

    如何选择持久化方案,取决于实际业务场景的需要,适合才是最重要的。RDB方案适合做冷备份,恢复数据时候数据比AOF快,而且快照时对写入服务影响小,但是会存在丢失数据,而且当数据量大的时候会存在服务短暂停止。AOF方案适合满足缓存一致性,而且当出现数据误删,可以采取将日志文件中误操作步骤删除就可以恢复数据。

     

  • 相关阅读:
    HDU 5247
    HDU 4965
    CodeForces 445B
    HDU 5835
    CodeForces 731C
    HDU 5783
    CodeForces 660D
    POJ 1631
    HDU 6112
    HDU 5860
  • 原文地址:https://www.cnblogs.com/wakee/p/10759449.html
Copyright © 2011-2022 走看看