• redis使用


    from my typora

    redis 使用

    redis基本命令

    一个redis实例可以包括多个数据库,客户端可以指定连接某个redis实例的哪个数据库,就好比一个mysql中创建多个数据库,客户端连接时指定连接哪个数据库。

    一个redis实例最多可以提供16个数据库,下标从0到15,客户端默认连接0号数据库,也可以通过select选择连接哪个数据库,如下连接1号库:

    lsnu@lsnu-Aspire-AG1731:/usr/local/redis$ ./bin/redis-cli
    127.0.0.1:6379> keys *
    (empty list or set)
    # select 同mysql中的use
    127.0.0.1:6379> select 0
    OK
    127.0.0.1:6379> keys *
    (empty list or set)
    127.0.0.1:6379> select 15
    OK
    127.0.0.1:6379[15]> keys *
    (empty list or set)
    127.0.0.1:6379[15]> select 16
    (error) ERR DB index is out of range
    # 退出和mysql相同:exit或者quit
    

    set [key]:设置一个键值对

    $ set name mzy
    

    get [key]:查看键值对:name

    $ get name
    

    del [key]:删除键值对:name

    $ del name
    

    keys *:查看当前数据库中的键值对(默认是0号库)

    # 查看所有
    $ keys *
    

    clear:清屏

    $ clear
    

    select [0-15]:从默认的0号库改变到1号库

    127.0.0.1:6379> select 1
    OK
    

    move [key] 0-15:将0号库中的name,移动到1号库中

    # 定位到0号库
    $ select 0
    # 移动到一号库
    $ move name 1
    # 查看当前0号库中是否存在name
    $ keys * / get name
    (empty list or set) / (nil)
    # 切换到1号库中,查看是否存在
    $ select 1
    $ keys * / get name
    1) "name" / "mzy"
    

    存放中文

    127.0.0.1:6379> set name 哈哈哈
    OK
    127.0.0.1:6379> get name
    "xe5x93x88xe5x93x88xe5x93x88"
    

    echo:redis中也可以使用echo命令,但是我认为没什么用;

    $ echo hhha
    hhha
    

    quit或exit:退出连接

    quit / exit # 都可以
    

    dbsize:返回当前数据库中key的数目

    $ dbsize
    127.0.0.1:6379> dbsize
    (integer) 2
    

    info:获取服务器的信息和统计

    $ info
    # Server
    ... 
    # Clients
    ... 
    # Memory
    ... 
    # Persistence
    ... 
    # Stats
    ... 
    # Replication
    ... 
    # CPU
    ... 
    # Cluster
    ... 
    # Keyspace
    ... 
    

    flushdb:删除当前选择数据库中的所有key:

    $ flushdb
    

    flushall:删除所有数据库的所有key:

    $ flushall
    

    redis做消息订阅与发布

    redis所特有的,消息发布订阅:

    开启三个redis客户端窗口:

    在第一个连接中,订阅mychat频道。此时如果没有人“发布”消息,当前窗口处于等待状态。

    127.0.0.1:6379> subscribe mychat
    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "mychat"
    3) (integer) 1
    

    在第二个窗口,向mychat窗口发布(publish)消息:

    127.0.0.1:6379> publish mychat '111'
    (integer) 1
    

    发现第一个窗口马上显示出了’111’

    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "mychat"
    3) (integer) 1
    1) "message"
    2) "mychat"
    3) "111"
    

    在第三个窗口中使用psubcribe,订阅多个频道:

    # 订阅所有以my* 开头的消息
    127.0.0.1:6379> psubscribe my*
    Reading messages... (press Ctrl-C to quit)
    1) "psubscribe"
    2) "my*"
    3) (integer) 1
    

    在第二个窗口中分别向mychat和mychat2发布消息:

    127.0.0.1:6379> publish mychat '111'
    (integer) 1
    127.0.0.1:6379> publish mychat '222'
    (integer) 2
    127.0.0.1:6379> publish mychat '333'
    (integer) 2
    127.0.0.1:6379> publish mychat2 '333'
    (integer) 1
    127.0.0.1:6379> 
    

    发现窗口1:

    127.0.0.1:6379> subscribe mychat
    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "mychat"
    3) (integer) 1
    1) "message"
    2) "mychat"
    3) "111"
    1) "message"
    2) "mychat"
    3) "222"
    1) "message"
    2) "mychat"
    3) "333"
    

    发现窗口3:

    127.0.0.1:6379> psubscribe my*
    Reading messages... (press Ctrl-C to quit)
    1) "psubscribe"
    2) "my*"
    3) (integer) 1
    1) "pmessage"
    2) "my*"
    3) "mychat"
    4) "222"
    1) "pmessage"
    2) "my*"
    3) "mychat"
    4) "333"
    1) "pmessage"
    2) "my*"
    3) "mychat2"
    4) "333"
    

    只有窗口3收到了mychat2。

    redis事务

    和众多数据库一样,redis作为NoSQL数据库同样也提供了事务机制。

    redis中的事务,通过MULTI/EXEC/DISCARD这三个命令实现事务。

    1.在redis中,事务直接被设置为最高级别,所有命令都会被串行化的顺序执行,事务执行期间,redis不会再为其它任何客户端请求提供任何服务,从而保证了事务中的所有命令被原子的执行。

    不要看redis是串行执行的,看起来好像很慢,其实不是,redis直接操作的内存,其实速度已经很快了;如果你设置它能为多个客户端同时提供服务,不通过串行的方式的话,我觉得反而是影响了redis的性能,因为这样来回切,进行隔离,反而降低了redis的执行速度!

    同时补充:如果现在你要从D盘复制两个文件(文件A、文件B)到E盘中,你会同时复制还是一个个复制?

    按照我们的惯性思维应该是同时复制,但是其实这样反而会更慢一些的,因为底层CPU要来回切换,一会儿复制一下文件A,一会儿复制一下文件B。切换反而更耗性能;由此说到了多线程编程,我认为大多数场景下多线程编程其实是不优的,除了一些特定的业务和逻辑场景,在我看来多线程编程大多数情况下很鸡肋。

    2.和关系型的数据中的事务相比,在redis事务中如果有某一条命令执行失败,其后命令仍然会被继续执行。

    而相比在我们的关系型数据库中,如果出现了事务异常,则会直接结束,不会往后执行了,并开始进行回滚。

    3.redis事务的流程:通过MULTI命令开启事务(同关系型数据库中的begin transaction),该命令执行之后,执行所有命令都被视为事务之内的操作,最后通过执行EXEC(提交)/DISCARD(回滚)来批量处理该事务之内的所有操作!

    multi:开启事务相当于关系型数据库中的begin transaction;

    exec:相当于关系型数据库中的commit;

    discard:相当于关系型数据库中的rollback;

    4.在事务开启之前如果出现通讯故障网络中断,其后所有待执行的语句都不会被服务器执行。然而如果网络中断发生在客户端执行EXEC命令之后,那么该事务中的所有命令都会被服务器执行。

    5、当使用Append-0Only模式时,Redis会通过调用系统函数write将该事务内的所有写操作在本次调用中全部写入磁盘。然而如果在写入的过程中出现系统崩溃,I如电源故障导致的宕机,那么此时也许只有部分数据被写入到磁盘,而另外一部分数据却已经丢失。Redis 服务器会在重新启动时执行一系列必要的一致性检测,一旦发现类似问题,就会立即退出并给出相应的错误提示。此时,我们就要充分利用Redis工具包中提供的redis- check-aof工具,该工具可以帮助我们定位到数据不一.致的错误,并将已经写入的部分数据进行回滚。修复之后我们就可以再次重新启动Redis服务器了。

    测试事务

    前:

    ​ incr,对一个数字进行增长,类似++:incr num 相当于 num++

    ​ incrby num 5,类似于num += 5:incr num 相当于 num = num + 5

    测试redis连通性:

    步骤1:在窗口1设置num,并获得数据

    127.0.0.1:6379> set num 1
    OK
    127.0.0.1:6379> get num 
    "1"
    

    步骤2:在窗口2,num累加1,并获得数据

    127.0.0.1:6379> get num
    "1"
    127.0.0.1:6379> incr num
    (integer) 2
    127.0.0.1:6379> get num
    "2"
    

    步骤3:在窗口1,获得数据

    127.0.0.1:6379> set num 1
    OK
    127.0.0.1:6379> get num 
    "1"
    127.0.0.1:6379> get num
    "2"
    # 发现已经受到影响
    

    步骤4:在窗口1,开启事务,多次累加数据

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> incr num
    QUEUED # 在排队中...
    127.0.0.1:6379> incr num
    QUEUED
    

    步骤5:在窗口2获得数据

    # 发现此刻数据并没有变化
    127.0.0.1:6379> get num
    "2"
    

    步骤6:在窗口1提交事务exec

    127.0.0.1:6379> exec
    1) (integer) 3
    2) (integer) 4
    

    步骤7:在窗口2查询num

    # 发现事务已经提交了
    127.0.0.1:6379> get num
    "4"
    

    步骤8:在窗口1再次累加(不开启事务)

    127.0.0.1:6379> incr num
    (integer) 5
    127.0.0.1:6379> incr num
    (integer) 6
    

    步骤9:窗口2查询

    # 受到影响
    127.0.0.1:6379> get num
    "6"
    

    步骤10:窗口1开启事务累加两次,然后discard。

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> incr num
    QUEUED
    127.0.0.1:6379> incr num
    QUEUED
    127.0.0.1:6379> discard
    OK
    

    步骤11:窗口2再次查询num

    # 发现事务没有提交了
    127.0.0.1:6379> get num
    "6"
    

    失败测试(测试和关系型数据库不一样的地方:在redis事务中如果有某一条命令执行失败,其后命令仍然会被继续执行。)

    # 首先把num清0,避免造成误导
    127.0.0.1:6379> set num 0
    OK
    # 开启事务
    127.0.0.1:6379> multi 
    OK
    # 增加5
    127.0.0.1:6379> incrby num 5
    QUEUED
    # 不可识别的x,造成异常
    127.0.0.1:6379> incrby num x
    QUEUED
    # 增加5
    127.0.0.1:6379> incrby num 5
    QUEUED
    # 提交执行事务
    127.0.0.1:6379> exec
    1) (integer) 5
    2) (error) ERR value is not an integer or out of range
    3) (integer) 10
    127.0.0.1:6379> get num
    "10"
    # 补:最后有人可能会想,如果我设置一个key为x,给一个数字的值,例如:5
    # 那redis,会不会引用呢?答案是不会,至少在incrby 中不会,已测试!
    

    补充:

    以上:

    ​ multi必须和exec或者discard成对出现,不然会出现:(error) ERR MULTI calls can not be nested

    redis的持久化

    redis持久化支持两种方式:RDB和AOF;可以二者单独使用,也可以将二者结合使用。

    RDB

    快照:snapshots(比较节省空间,很快),记录当前在内存中的状态(只用记当前,不管过程)。

    RDB的优势:

    持久化只有一个文件,易于备份;并且因为是快照,只存数据的缘故,启动比AOF更快(数据量较大的情况下)。

    在redis的根目录下,发现多了一个dump.rdb,就是redis持久化存储的数据(RDB方式下的)

    lsnu@lsnu-Aspire-AG1731:/usr/local/redis$ ll
    总用量 80
    drwxr-xr-x  3 root root  4096 11月 10 16:29 ./
    drwxr-xr-x 11 root root  4096 11月  9 18:02 ../
    drwxr-xr-x  2 root root  4096 11月  9 18:06 bin/
    -rw-r--r--  1 root root   151 11月 10 16:29 dump.rdb
    -rw-r--r--  1 root root 62156 11月  9 18:23 redis.conf
    

    所以归档就很容易了:直接备份dump.rdb这一个文件就好了!

    RDB的劣势:

    数据的高可用性无法保证,系统宕机的话,会造成数据丢失。

    RDB采用fork子进程协助完成持久化,一旦数据量大了,可能造成服务器停止服务0-1000ms的情况。

    RDB快照参数设置:
    # 在redis.conf 中配置
    save 900 1     # 每900秒,15分钟(如果有1个key发生变化),则dump内存快照。
    save 300 10    # 每300秒,5分钟(如果有10个key发生变化),则dump内存快照。
    save 60  10000 # 每60秒,1分钟(如果有10000个key发生变化),则dump内存快照。
    

    AOF

    以日志的方式记录,(记录了过程,做了什么,记下命令,记录修改、删除或者增加的操作;但是查询忽略了)

    只要更改了redis,就记录下这些命令;原理就是,每次启动redis,把从最初开始执行过的所有:增、删、改命令全部执行一遍来恢复到当前状态。

    AOF的劣势

    1.相同数量的数据集,AOF文件通常大于RDB文件

    2.同步的策略不同,导致AOF在运行上效率慢于RDB。

    AOF的配置
    always # 每次有数据修改都会写入AOF文件
    everysec # 每秒钟同步一次,该策略为AOF的缺省策略
    no # 从不同步。高效但是不会持久化。
    
    # 默认是关闭的
    appendonly no -> appendonly yes
    
    # appendfsync always
    appendfsync everysec
    # appendfsync no
    

    无持久化

    就做缓存,不持久化。

  • 相关阅读:
    Aruba无线控制器添加黑名单
    H3C POE交换机办公网常用配置
    H3C接入交换机办公网常用配置
    H3C核心交换机办公网常用配置
    H3C IRF-原理
    华为交换机SSH远程配置
    H3C无线AC黑白名单配置
    H3C 5130交换机初始化配置
    H3C交换机恢复出厂设置
    H3C交换机SSH登录配置
  • 原文地址:https://www.cnblogs.com/mzywucai/p/11053335.html
Copyright © 2020-2023  润新知