zoukankan      html  css  js  c++  java
  • redis 基础学习总结

    背景:因为项目用到了redis,加上之前一直听说了redis,但一直没有用过,正好项目现在要用到了,抽时间简单学习了下,做个记录总结下。

    一 、Redis简介

    介绍Redis之前,先了解下NoSQL (Not noly SQL)不仅仅是SQL

    属于非关系型数据库;Redis就属于非关系型数据库

    传统的Mysql ,oracle ,sql server 等 都是关系型数据库

     

    为什么需要NoSQL,主要应对以下问题,传统关系型数据库力不从心

    High performance -高并发读写

    Huge Storage-海量数据的高效率存储和访问

    High Scalablility && High Availability 高可扩展性和高可用性

     

    NoSQL 产品 MongoDB Redis等等  Redis目前主流

     

    NoSQL的特点

    易扩展

    灵活的数据模型

    大数据量,高性能

    高可用

     

    高性能键值对数据库,支持的键值数据类型

    字符串类型

    列表类型

    有序集合类型

    散列类型

    集合类型

     

    Redis的应用场景

    缓存

    任务队列

    网站访问统计

    数据过期处理

    应用排行榜

    分布式集群架构中的session分离

    二、Redis安装

    Redis从一开始就只支持Linux,后面虽然有团队搞出Window版本,但是我还是建议大伙安装到Linux中。

     

    准备工作 VMware 以及Xshell 

    https://redis.io/

     

    redis官方安装教程,但是比较简单,不适合生产环境的安装部署;

    我们这边详细点,

     

    第一步:安装gcc

    gcc编译c的,因为redis是c编写的,所以我们先安装下gcc

    yum install gcc-c++

     

    第二步:wget方式 下载redis压缩包,并解压,以及编译

    下载

    wget http://download.redis.io/releases/redis-3.2.9.tar.gz

    解压

    tar -zxvf redis-3.2.9.tar.gz

     

    [root@localhost ~]# ll

    总用量 1548

    -rw-------. 1 root root    1261 6月  27 19:54 anaconda-ks.cfg

    -rw-r--r--. 1 root root   25680 4月  27 18:45 mysql57-community-release-el7-11.noarch.rpm

    drwxrwxr-x. 6 root root    4096 5月  17 23:39 redis-3.2.9

    -rw-r--r--. 1 root root 1547695 5月  17 23:40 redis-3.2.9.tar.gz

    [root@localhost ~]# 

    这样/root/目录下就有redis了

     

    编译:

    cd redis-3.2.9

    进入目录,

    make

    编译

     

     

    第三步:安装redis

    make PREFIX=/usr/local/redis install

    安装到/usr/local/redis/

    QQ鎴�浘20170702164458.jpg

     

    已经有redis 

    [root@localhost local]# cd redis/

    [root@localhost redis]# ll

    总用量 0

    drwxr-xr-x. 2 root root 134 7月   2 16:44 bin

    [root@localhost redis]# 

     

    redis里有个bin

    [root@localhost redis]# cd bin/

    [root@localhost bin]# ll

    总用量 15060

    -rwxr-xr-x. 1 root root 2431832 7月   2 16:44 redis-benchmark

    -rwxr-xr-x. 1 root root   25168 7月   2 16:44 redis-check-aof

    -rwxr-xr-x. 1 root root 5181840 7月   2 16:44 redis-check-rdb

    -rwxr-xr-x. 1 root root 2584848 7月   2 16:44 redis-cli

    lrwxrwxrwx. 1 root root      12 7月   2 16:44 redis-sentinel -> redis-server

    -rwxr-xr-x. 1 root root 5181840 7月   2 16:44 redis-server

    [root@localhost bin]# 

    bin里是一些工具

     

    cd回到root,我们需要把一个配置文件 复制到 redis下 后台启动用到

     

    QQ鎴�浘20170702164811.jpg

     

    [root@localhost redis-3.2.9]# cp redis.conf /usr/local/redis/

    [root@localhost redis-3.2.9]# ll /usr/local/redis/

    总用量 48

    drwxr-xr-x. 2 root root   134 7月   2 16:44 bin

    -rw-r--r--. 1 root root 46695 7月   2 16:49 redis.conf

    [root@localhost redis-3.2.9]# 

     

    第四步:启动和关闭redis服务

    启动redis就是执行redis里的bin里的redis-server命令

    进入redis目录 执行

    [root@localhost redis-3.2.9]# cd /usr/local/redis/

    [root@localhost redis]# bin/redis-server

     

    QQ鎴�浘20170702180602.jpg

     

    出现这种图标,说明启动成功;

     

    但是 ,这种启动是前端或者前台启动,假如退出 程序就终止或者退出了。

    所以这种服务程序,必须后端运行;

     

    我们通过修改配置文件redis.conf 

     

    操作,

    我们ctrl+c 退出当前程序;

    vi打开redis.conf  vi /usr/local/redis/redis.conf 

    找到

    QQ鎴�浘20170702202245.jpg

     

    把no改成yes

    esc退出 !wq保存;

     

    然后进入redis目录,然后加载配置文件运行;

    [root@localhost ~]# cd /usr/local/redis/

    [root@localhost redis]# ./bin/redis-server ./redis.conf 

     

    我们通过ps -ef | grep -i redis命令来搜索redis服务

    [root@localhost redis]# ps -ef | grep -i redis

    root       8692      1  0 16:52 ?        00:00:19 bin/redis-server *:6379

    root       8954   8930  0 20:30 pts/0    00:00:00 grep --color=auto -i redi

    [root@localhost redis]# 

     

    我们通过shutdown命令来停止redis服务的运行

    [root@localhost redis]# ./bin/redis-cli shutdown

    [root@localhost redis]# ps -ef | grep -i redis

    root       8959   8930  0 20:35 pts/0    00:00:00 grep --color=auto -i redi

    [root@localhost redis]# 

     

     

    第五步:redis基本使用

    [root@localhost redis]# ./bin/redis-cli

    127.0.0.1:6379> 

    进入客户端

    我们存储 name:java1234

    key:value格式

    127.0.0.1:6379> set name java1234

    OK

    127.0.0.1:6379> get name

    "java1234"

    通过set设置,通过get获取

     

    127.0.0.1:6379> keys *

    1) "name"

    127.0.0.1:6379> del name

    (integer) 1

    127.0.0.1:6379> keys *

    (empty list or set)

    127.0.0.1:6379> 

     

    通过del删除key,keys  * 显示所有keys

    三、Jedis简介

    实际开发中,我们需要用Redis的连接工具连接Redis然后操作Redis,

    对于主流语言,Redis都提供了对应的客户端;

     

    https://redis.io/clients

     

    QQ鎴�浘20170708104553.jpg

     

    https://redis.io/clients#java

     

    QQ鎴�浘20170708104732.jpg

     

    提供了很多客户端 官方推荐的是Jedis  托管地址:https://github.com/xetorthio/jedis

    四、Jedis连接 HelloWorld实现

    建一个Maven项目,

    pom里加下jedis依赖,

    1
    2
    3
    4
    5
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.java1234.redis;
     
    import redis.clients.jedis.Jedis;
     
    /**
     * 测试类
     * @author user
     *
     */
    public class JedisTest {
     
        public static void main(String[] args) {
            Jedis jedis=new Jedis("192.168.1.107",6379); // 创建客户端 设置IP和端口
            jedis.set("name""java知识分享网"); // 设置值
            String value=jedis.get("name"); // 获取值
            System.out.println(value);
            jedis.close(); // 释放连接资源
        }
    }

    测试代码,

    运行 报错了

    QQ鎴�浘20170708163732.jpg

    连接超时,

     

    我们配置下防火墙 开一个6379端口权限

    firewall-cmd --zone=public --add-port=6379/tcp --permanent

    firewall-cmd --reload

     

    继续运行 还是报错 连接超时 错误;

     

    我们配置下 redis配置文件

    [root@localhost redis]# vi /usr/local/redis/redis.conf

     

    QQ鎴�浘20170708164341.jpg

     

    这里绑定了本机,我们把这个备注掉;

    # bind 127.0.0.1

     

    配置完后 

    [root@localhost redis]# ./bin/redis-cli shutdown

    [root@localhost redis]# ./bin/redis-server ./redis.conf

    要重启下redis服务;

     

    继续运行 又报错了

    Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.

    at redis.clients.jedis.Protocol.processError(Protocol.java:127)

    at redis.clients.jedis.Protocol.process(Protocol.java:161)

    at redis.clients.jedis.Protocol.read(Protocol.java:215)

    at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340)

    at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:239)

    at redis.clients.jedis.Jedis.set(Jedis.java:121)

    at com.java1234.redis.JedisTest.main(JedisTest.java:14)

     

    这个是因为远程连接redis redis自我保护 拒绝访问;

     

    有两种方法 解决

    第一种 直接去掉自我保护功能(不推荐)

    [root@localhost redis]# vi /usr/local/redis/redis.conf

    进入配置

    找到 protected-mode yes

    QQ鎴�浘20170708164718.jpg

     

    改成 no即可

     

    编辑后 重启redis服务,然后运行 ,结果出来了

    QQ鎴�浘20170708164855.jpg

     

    第二种 设置redis连接密码

    进入客户端

    [root@localhost redis]# ./bin/redis-cli

    127.0.0.1:6379> config set requirepass 123456

    设置密码 123456

     

    127.0.0.1:6379> quit

    [root@localhost redis]# ./bin/redis-cli

    127.0.0.1:6379> auth 123456

    OK

     

    说明设置成功

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    package com.java1234.redis;
     
    import redis.clients.jedis.Jedis;
     
    /**
     * 测试类
     * @author user
     *
     */
    public class JedisTest {
     
        public static void main(String[] args) {
            Jedis jedis=new Jedis("192.168.1.107",6379); // 创建客户端 设置IP和端口
            jedis.auth("123456"); // 设置密码
            jedis.set("name""java知识分享网"); // 设置值
            String value=jedis.get("name"); // 获取值
            System.out.println(value);
            jedis.close(); // 释放连接资源
        }
    }

    QQ鎴�浘20170708224324.jpg

     

    这样就OK了

    连接池:

    package com.java1234.redis;
     
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
     
    /**
     * 测试类
     * @author user
     *
     */
    public class JedisTest {
     
        public static void main(String[] args) {
            JedisPoolConfig config=new JedisPoolConfig(); // 连接池的配置对象
            config.setMaxTotal(100); // 设置最大连接数
            config.setMaxIdle(10); // 设置最大空闲连接数
             
            JedisPool jedisPool=new JedisPool(config,"192.168.1.107",6379);
             
            Jedis jedis=null;
            try{
                jedis=jedisPool.getResource(); // 获取连接
                jedis.auth("123456"); // 设置密码
                jedis.set("name", "java知识分享网"); // 设置值
                String value=jedis.get("name"); // 获取值
                System.out.println(value);
                 
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                if(jedis!=null){
                    jedis.close();
                }
                if(jedisPool!=null){
                    jedisPool.close();
                }
            }
        }
    }

    五、Redis的数据结构之字符串

    五种数据类型:

    字符串(String)

    字符串列表(list)

    有序字符串集合(sorted set)

    哈希(hash)

    字符串集合(set)

     

    Key定义的注意点:

    不要过长,

    不要过短,

    统一的命名规范

     

    存储String

    二进制安全的,存入和获取的数据相同

    Value最多可以容纳的数据长度是512M

     

    存储String常用命令

    赋值

    取值

    删除

    数值增减

    扩展命令

     

    [root@localhost redis]# ./bin/redis-cli

    赋值

    127.0.0.1:6379> set name java1234

    OK

     

    取值

    127.0.0.1:6379> get name

    "java1234"

     

    获取并设置值

    127.0.0.1:6379> getset name open1111

    "java1234"

    127.0.0.1:6379> get name

    "open1111"

     

    删除

    127.0.0.1:6379> del name

    (integer) 1

    127.0.0.1:6379> get name

    (nil)

     

    incr 自增 

    假如没有定义 则默认0

    假如非数值类型 则报错

    127.0.0.1:6379> incr n

    (integer) 1

    127.0.0.1:6379> get n

    "1"

     

    127.0.0.1:6379> set nn 2

    OK

    127.0.0.1:6379> incr nn

    (integer) 3

    127.0.0.1:6379> get nn

    "3"

    127.0.0.1:6379> 

     

    127.0.0.1:6379> set n2 java1234

    OK

    127.0.0.1:6379> incr n2

    (error) ERR value is not an integer or out of range

    127.0.0.1:6379> 

     

    自减 decr 同上

    127.0.0.1:6379> decr nn

    (integer) 2

    127.0.0.1:6379> decr n3

    (integer) -1

     

    扩展 

    incrby 指定增量值

    127.0.0.1:6379> incrby n3 8

    (integer) 7

     

    decrby 指定减量值

    127.0.0.1:6379> decrby n3 5

    (integer) 2

     

    append 追加字符串

    假如没定义 直接赋值

    127.0.0.1:6379> append s1 jj

    (integer) 2

    127.0.0.1:6379> get s1

    "jj"

    127.0.0.1:6379> append s1 bb

    (integer) 4

    127.0.0.1:6379> get s1

    "jjbb"

    六、Redis的数据结构之哈希

    存储Hash

     String key和String Value的Map容器

     

    每一个Hash可以存储4294967295个键值对

     

    存储Hash常用命令:

    赋值  

    取值

    删除

    增加数字

    判断字段是否存在

    获取hash属性个数

    获取hash所有属性名称

     

    定义h1 以及username和password字段 值分别是java1234 123456

     

    hget单个字段设置

     

    127.0.0.1:6379> hset h1 username java1234

    (integer) 1

    127.0.0.1:6379> hset h1 password 123456

    (integer) 1

    127.0.0.1:6379> hget h1 username

    "java1234"

    127.0.0.1:6379> hget h1 password

    "123456"

     

    hmset 多个字段一起设置

    127.0.0.1:6379> hmset h2 username open1111 password 23456

    OK

    127.0.0.1:6379> hmget h2 username

    1) "open1111"

    127.0.0.1:6379> hmget h2 password

    1) "23456"

    127.0.0.1:6379> hmget h2 username password

    1) "open1111"

    2) "23456"

     

    127.0.0.1:6379> hgetall h2

    1) "username"

    2) "open1111"

    3) "password"

    4) "23456"

     

    hdel删除属性

    可以一次删除一个或者多个

    127.0.0.1:6379> hdel h2 username password

    (integer) 2

    127.0.0.1:6379> hgetall h2

    (empty list or set)

     

    hincrby增加数字

    127.0.0.1:6379> hset h1 age 20

    (integer) 1

    127.0.0.1:6379> hincrby h1 age 5

    (integer) 25

     

    hexists判断字段是否存在 1表示存在 0表示不存在

    127.0.0.1:6379> hexists h1 age

    (integer) 1

    127.0.0.1:6379> hexists h1 age2

    (integer) 0

     

    hlen获取hash属性个数

    127.0.0.1:6379> hlen h1

    (integer) 3

    127.0.0.1:6379> hlen h2

    (integer) 0

     

    hkeys获取所有属性名称

    127.0.0.1:6379> hkeys h1

    1) "username"

    2) "password"

    3) "age"

    127.0.0.1:6379> hkeys h2

    (empty list or set)

     

    hvals获取所有属性值

    127.0.0.1:6379> hvals h1

    1) "java1234"

    2) "123456"

    3) "25"

    127.0.0.1:6379> hvals h2

    (empty list or set)

    127.0.0.1:6379> 

    七、Redis的数据结构之List

    存储list:

    ArrayList使用数组方式

    LinkedList使用双向链接方式

     

    双向链接表中增加数据

    双向链接表中删除数据

     

    存储list常用命令

    两端添加

    两端弹出

    扩展命令

     

    lpush 方式添加

    从左边开始添加

    127.0.0.1:6379> lpush l1 a b c d

    (integer) 4

    127.0.0.1:6379> lpush l1 1 2 3 4

    (integer) 8

     

    lrange 获取指定方位的集合元素

     

    从第1个开始 到倒数第一个 也就是最后一个 也就是 所有数据

    127.0.0.1:6379> lrange l1 0 -1

    1) "4"

    2) "3"

    3) "2"

    4) "1"

    5) "d"

    6) "c"

    7) "b"

    8) "a"

     

    获取从第1个到第6个集合元素

    127.0.0.1:6379> lrange l1 0 6

    1) "4"

    2) "3"

    3) "2"

    4) "1"

    5) "d"

    6) "c"

    7) "b"

     

    rpush 从右端开始添加(一般人比较习惯这种方式)

    127.0.0.1:6379> rpush l2 a b c d

    (integer) 4

    127.0.0.1:6379> rpush l2 1 2 3 4

    (integer) 8

    127.0.0.1:6379> lrange l2 0 -1

    1) "a"

    2) "b"

    3) "c"

    4) "d"

    5) "1"

    6) "2"

    7) "3"

    8) "4"

    127.0.0.1:6379> lrange l2 0 6

    1) "a"

    2) "b"

    3) "c"

    4) "d"

    5) "1"

    6) "2"

    7) "3"

     

    lpop 左侧弹出集合元素

    rpop 右侧弹出集合元素

    127.0.0.1:6379> lrange l2 0 -1

    1) "b"

    2) "c"

    3) "d"

    4) "1"

    5) "2"

    6) "3"

    7) "4"

    127.0.0.1:6379> rpop l2

    "4"

    127.0.0.1:6379> lrange l2 0 -1

    1) "b"

    2) "c"

    3) "d"

    4) "1"

    5) "2"

    6) "3"

     

    llen查看元素个数

    127.0.0.1:6379> llen l2

    (integer) 6

     

    lpushx 集合头部插入元素

    127.0.0.1:6379> lpushx l2 xx

    (integer) 7

    127.0.0.1:6379> lrange l2 0 -1

    1) "xx"

    2) "b"

    3) "c"

    4) "d"

    5) "1"

    6) "2"

    7) "3"

     

     

     

    rpushx 集合尾部插入元素

    127.0.0.1:6379> rpushx l2 yy

    (integer) 8

    127.0.0.1:6379> lrange l2 0 -1

    1) "xx"

    2) "b"

    3) "c"

    4) "d"

    5) "1"

    6) "2"

    7) "3"

    8) "yy"

     

    lpush集合头部插入多个元素

    127.0.0.1:6379> lpush l2 a1 a2 

    (integer) 10

    127.0.0.1:6379> lrange l2 0 -1

     1) "a2"

     2) "a1"

     3) "xx"

     4) "b"

     5) "c"

     6) "d"

     7) "1"

     8) "2"

     9) "3"

    10) "yy"

     

    127.0.0.1:6379> rpush l2 a3 a4

    (integer) 12

    127.0.0.1:6379> lrange l2 0 -1

     1) "a2"

     2) "a1"

     3) "xx"

     4) "b"

     5) "c"

     6) "d"

     7) "1"

     8) "2"

     9) "3"

    10) "yy"

    11) "a3"

    12) "a4"

     

    lrem 从指定方向删除指定个数的指定元素

    先加点数据搞个新集合l3

    127.0.0.1:6379> lpush l3 1 3 2 3 2 1 2 1 3

    (integer) 9

    127.0.0.1:6379> lrange l3 0 -1

    1) "3"

    2) "1"

    3) "2"

    4) "1"

    5) "2"

    6) "3"

    7) "2"

    8) "3"

    9) "1"

     

    从左边开始删除2个1

    127.0.0.1:6379> lrem l3 2 1

    (integer) 2

    127.0.0.1:6379> lrange l3 0 -1

    1) "3"

    2) "2"

    3) "2"

    4) "3"

    5) "2"

    6) "3"

    7) "1"

     

    从右边开始删除2个3

    127.0.0.1:6379> lrem l3 -2 3

    (integer) 2

    127.0.0.1:6379> lrange l3 0 -1

    1) "3"

    2) "2"

    3) "2"

    4) "2"

    5) "1"

     

    删除所有2

    127.0.0.1:6379> lrem l3 0 2

    (integer) 3

    127.0.0.1:6379> lrange l3 0 -1

    1) "3"

    2) "1"

     

    lset 设置集合指定索引的值

    127.0.0.1:6379> lrange l1 0 -1

    1) "4"

    2) "3"

    3) "2"

    4) "1"

    5) "d"

    6) "c"

    7) "b"

    8) "a"

     

    索引从0开始

    127.0.0.1:6379> lset l1 3 xxxx

    OK

    127.0.0.1:6379> lrange l1 0 -1

    1) "4"

    2) "3"

    3) "2"

    4) "xxxx"

    5) "d"

    6) "c"

    7) "b"

    8) "a"

     

    linsert 在集合里插入指定元素

    在xxxx元素之前插入aa

    127.0.0.1:6379> linsert l1 before xxxx aa

    (integer) 9

    127.0.0.1:6379> lrange l1 0 -1

    1) "4"

    2) "3"

    3) "2"

    4) "aa"

    5) "xxxx"

    6) "d"

    7) "c"

    8) "b"

    9) "a"

     

    在xxxx元素之后插入bb

    127.0.0.1:6379> linsert l1 after xxxx bb

    (integer) 10

    127.0.0.1:6379> lrange l1 0 -1

     1) "4"

     2) "3"

     3) "2"

     4) "aa"

     5) "xxxx"

     6) "bb"

     7) "d"

     8) "c"

     9) "b"

    10) "a"

     

    rpoplpush 把A集合尾部元素弹出并插入到B集合头部

    127.0.0.1:6379> rpush l4 a b c

    (integer) 3

    127.0.0.1:6379> rpush l5 1 2 3

    (integer) 3

    127.0.0.1:6379> lrange l4 0 -1

    1) "a"

    2) "b"

    3) "c"

    127.0.0.1:6379> lrange l5 0 -1

    1) "1"

    2) "2"

    3) "3"

    127.0.0.1:6379> rpoplpush l4 l5

    "c"

    127.0.0.1:6379> lrange l4 0 -1

    1) "a"

    2) "b"

    127.0.0.1:6379> lrange l5 0 -1

    1) "c"

    2) "1"

    3) "2"

    4) "3"

     

    八、Redis的数据结构之Set

    存储Set

     和List类型不同的是,Set集合中不允许出现重复的元素

     Set可包含的最大元素数量是4294967295

    存储set常用命令:

    添加/删除元素

    获取集合中的元素

    集合中的差集运算

    集合中的交集运算

    集合中的并集元算

    扩展命令

     

    sadd key member [member ...]

    添加set元素

    127.0.0.1:6379> sadd set1  a b c

    (integer) 3

    添加三个元素

    smembers key

    查看指定key集合元素

    127.0.0.1:6379> smembers set1

    1) "c"

    2) "b"

    3) "a"

     

    127.0.0.1:6379> sadd set1 a d e

    (integer) 2

    127.0.0.1:6379> smembers set1

    1) "c"

    2) "d"

    3) "b"

    4) "a"

    5) "e"

    继续添加元素 发现 重复元素不再添加

     

    srem key member [member ...]

    删除元素

    127.0.0.1:6379> srem set1 a d

    (integer) 2

    127.0.0.1:6379> smembers set1

    1) "b"

    2) "c"

    3) "e"

    删除两个元素

     

    sismember key member

    判断某个元素是否存在 返回1 表示存在 返回0表示不存在

    127.0.0.1:6379> sismember set1 a

    (integer) 0

    127.0.0.1:6379> sismember set1 b

    (integer) 1

     

    sdiff计算差集

    127.0.0.1:6379> sadd set2 a b c

    (integer) 3

    127.0.0.1:6379> sadd set3 b c d e

    (integer) 4

    127.0.0.1:6379> sdiff set2 set3

    1) "a"

    127.0.0.1:6379> sdiff set3 set2

    1) "d"

    2) "e"

    我们发现 集合的顺序不同 结果不一样 根据前者参考

     

    sinter计算交集

    127.0.0.1:6379> sinter set2 set3

    1) "c"

    2) "b"

     

    sunion计算并集

    127.0.0.1:6379> sunion set2 set3

    1) "e"

    2) "a"

    3) "b"

    4) "c"

    5) "d"

     

    scard计算元素总数

    127.0.0.1:6379> smembers set1

    1) "b"

    2) "c"

    3) "e"

    127.0.0.1:6379> scard set1

    (integer) 3

     

    srandmember 随机取一个元素

    127.0.0.1:6379> srandmember set1

    "c"

    127.0.0.1:6379> srandmember set1

    "e"

     

    sdiffstore 把差集结果存储到新集合中

    127.0.0.1:6379> smembers set2

    1) "c"

    2) "b"

    3) "a"

    127.0.0.1:6379> smembers set3

    1) "c"

    2) "e"

    3) "d"

    4) "b"

    127.0.0.1:6379> sdiffstore r1 set2 set3

    (integer) 1

    127.0.0.1:6379> smembers r1

    1) "a"

     

    sinterstore 把交集结果存储到新集合中

    127.0.0.1:6379> sinterstore r2 set2 set3

    (integer) 2

    127.0.0.1:6379> smembers r2

    1) "c"

    2) "b"

     

    sunionstore把并集结果存储到新集合中

    127.0.0.1:6379> sunionstore r3 set2 set3

    (integer) 5

    127.0.0.1:6379> smembers r3

    1) "e"

    2) "a"

    3) "b"

    4) "c"

    5) "d"

     

    存储Set使用场景

     跟踪一些唯一性数据

     用于维护数据对象之间的关联关系

    九、Redis持久化

    所有的数据都存在内存中,从内存当中同步到硬盘上,这个过程叫做持久化过程

    持久化操作,两种方式:rdb方式、aof方式,可以单独使用或者结合使用。

    使用方法:

     rdb持久化方法:在指定的时间间隔写入硬盘

    aof方式:将以日志,记录每一个操作,服务器启动后就构建数据库。

    配置可以禁用 持久化功能。

    也可以同时使用两种方式。

    Redis的持久化之RDB方式:

    RDB方式 Redis是默认支持的

    优势:只有一个文件,时间间隔的数据,可以归档为一个文件,方便压缩转移(就一个文件)

    劣势:如果宕机,数据损失比较大,因为它是没一个时间段进行持久化操作的。也就是积攒的数据比较多,一旦懵逼,就彻底懵逼了

    配置:

    [root@localhost redis]# vi redis.conf 

    编辑redis.conf

    往下拉:

    QQ鎴�浘20170718091223.jpg

     

    这里save 900 1 表示 每900秒内至少有1个kery发生变化,就持久化

    save 300 10表示 每300秒内至少有10个key发生变化,就持久化

    save 60 10000表示 每60秒内至少有10000个key发生变化,就持久化

     

    再往下拉:

    QQ鎴�浘20170718091658.jpg

     

    这里有个dbfilename配置 是 保存的持久化的文件名 默认是dump.rdb

     

    再往下:

    QQ鎴�浘20170718091821.jpg

     

    dir ./ 表示文件存储路径是当前路径;

     

     

    我们退出

    QQ鎴�浘20170718092622.jpg

     

    当前路径里确实是有这个文件的。

     

     

    RDB北风和恢复数据  

    假如遇到断电或者宕机或者自然灾害, 我们需要恢复数据 我们模拟下。

    我们先重置下数据

    shutdown关闭下redis

    127.0.0.1:6379> shutdown

    not connected> exit

    [root@localhost redis]# ll

    总用量 52

    drwxr-xr-x. 2 root root   134 7月   6 09:18 bin

    -rw-r--r--. 1 root root    99 7月  18 10:41 dump.rdb

    -rw-r--r--. 1 root root 46697 7月  18 10:41 redis.conf

    然后删除掉rdb文件,再启动redis

    [root@localhost redis]# rm -rf dump.rdb 

    [root@localhost redis]# ll

    总用量 48

    drwxr-xr-x. 2 root root   134 7月   6 09:18 bin

    -rw-r--r--. 1 root root 46697 7月  18 10:41 redis.conf

    [root@localhost redis]# ./bin/redis-server ./redis.conf 

    [root@localhost redis]# ./bin/redis-cli

    127.0.0.1:6379> keys *

    (empty list or set)

    这时候是没有数据的

     

    这时候启动 是没数据的

    [root@localhost redis]# ./bin/redis-server ./redis.conf 

    [root@localhost redis]# ./bin/redis-cli

    127.0.0.1:6379> keys *

    (empty list or set)

     

    我们搞几个key,然后shutdown save 保存退出

    127.0.0.1:6379> set n1 1

    OK

    127.0.0.1:6379> set n2 2

    OK

    127.0.0.1:6379> set n3 3

    OK

    127.0.0.1:6379> shutdown save

    not connected> exit

     

    假如这时候 我们再重启redis 这时候启动过程会进程rdb check验证 然后加载redis目录下rdb文件;加载数据;

    我们验证下:

     

    我们再次启动

    [root@localhost redis]# ./bin/redis-server ./redis.conf 

    [root@localhost redis]# ./bin/redis-cli

    127.0.0.1:6379> keys *

    1) "n1"

    2) "n3"

    3) "n2"

    说明是数据加载进来了;

     

    这里我们把redis下的rdb文件剪切到其他地方去 然后再启动试下

    [root@localhost redis]# ll

    总用量 52

    drwxr-xr-x. 2 root root   134 7月  18 11:05 bin

    -rw-r--r--. 1 root root    99 7月  18 11:35 dump.rdb

    -rw-r--r--. 1 root root 46697 7月  18 10:41 redis.conf

    [root@localhost redis]# mv dump.rdb /root/

    [root@localhost redis]# ll

    总用量 48

    drwxr-xr-x. 2 root root   134 7月  18 11:05 bin

    -rw-r--r--. 1 root root 46697 7月  18 10:41 redis.conf

    [root@localhost redis]# ll /root/

    总用量 8

    -rw-------. 1 root root 1261 7月   6 05:42 anaconda-ks.cfg

    -rw-r--r--. 1 root root   99 7月  18 11:35 dump.rdb

    -rw-r--r--. 1 root root    0 7月  13 22:00 java牛逼

    drwxr-xr-x. 2 root root    6 7月  13 22:07 java书籍

     

    剪切到了root下

     

    这时候再启动下:

    [root@localhost redis]# ./bin/redis-server ./redis.conf 

    [root@localhost redis]# ./bin/redis-cli

    127.0.0.1:6379> keys *

    (empty list or set)

    数据没了

     

    恢复数据的话 我们只需要把备份文件搞到redis下即可

    再复制过来即可:

    [root@localhost redis]# cp /root/dump.rdb /usr/local/redis/

    cp:是否覆盖"/usr/local/redis/dump.rdb"? y

    [root@localhost redis]# ./bin/redis-server ./redis.conf 

    [root@localhost redis]# ./bin/redis-cli

    127.0.0.1:6379> keys *

    1) "n2"

    2) "n1"

    3) "n3"

     

    这时候 数据就有了 这就是恢复过程;

     

    绕了一大圈 总结下

    平时我们可以定期把rdb文件备份到指定地方 需要恢复的时候 直接把rdb搞到redis下即可;

     Redis的持久化之AOF方式

    AOF方式:将以日志,记录每一个操作

    优势:安全性相对RDB方式高很多;

    劣势:效率相对RDB方式低很多;

    配置:

    [root@localhost redis]# vi redis.conf 

     

    编辑redis.conf

     

    往下拉 找到:

    QQ鎴�浘20170718094504.jpg

     

    appendonly no默认关闭aof方式 我们修改成yes 就开启

    下面那个是默认的aof文件名

     

    再往下拉:

    QQ鎴�浘20170718094518.jpg

     

    这里是三种同步策略:

    always 是 只要发生修改,立即同步 (推荐实用 安全性最高)

    everysec 是 每秒同步一次

    no是不同步 

     

    我们修改成always

     

    然后保存 退出;

     

    我们重新启动redis,然后随便加几个key

     

    QQ鎴�浘20170718103620.jpg

     

    这里就有一个appendonly.aof文件;

     

    aof方式恢复数据

     

    我们先重置数据

    [root@localhost redis]# rm -rf dump.rdb 

    [root@localhost redis]# ll

    总用量 48

    drwxr-xr-x. 2 root root   134 7月  18 11:05 bin

    -rw-r--r--. 1 root root 46698 7月  18 12:14 redis.conf

     

    启动redis

    [root@localhost redis]# ./bin/redis-server ./redis.conf 

    [root@localhost redis]# ./bin/redis-cli

    127.0.0.1:6379> keys *

    (empty list or set)

    目前数据库是空

     

    添加数据

    127.0.0.1:6379> set n1 1

    OK

    127.0.0.1:6379> set n2 2

    OK

    127.0.0.1:6379> set n3 3

    OK

    127.0.0.1:6379> shutdown nosave

    not connected> exit

    [root@localhost redis]# ll

    总用量 52

    -rw-r--r--. 1 root root   107 7月  18 12:17 appendonly.aof

    drwxr-xr-x. 2 root root   134 7月  18 11:05 bin

    -rw-r--r--. 1 root root 46698 7月  18 12:14 redis.conf

    [root@localhost redis]# 

     

    我们把aof文件剪切到其他地方去 然后启动试下

    [root@localhost redis]# mv appendonly.aof /root/

    [root@localhost redis]# ll

    总用量 48

    drwxr-xr-x. 2 root root   134 7月  18 11:05 bin

    -rw-r--r--. 1 root root 46698 7月  18 12:14 redis.conf

    [root@localhost redis]# ./bin/redis-server ./redis.conf 

    [root@localhost redis]# ./bin/redis-cli

    127.0.0.1:6379> keys *

    (empty list or set)

    没数据;

     

    我们再把aof文件复制回来;

    [root@localhost redis]# cp /root/appendonly.aof /usr/local/redis/

    cp:是否覆盖"/usr/local/redis/appendonly.aof"? y

    [root@localhost redis]# ll

    总用量 52

    -rw-r--r--. 1 root root   107 7月  18 12:22 appendonly.aof

    drwxr-xr-x. 2 root root   134 7月  18 11:05 bin

    -rw-r--r--. 1 root root 46698 7月  18 12:14 redis.conf

    [root@localhost redis]# ./bin/redis-server ./redis.conf 

    [root@localhost redis]# ./bin/redis-cli

    127.0.0.1:6379> keys *

    1) "n1"

    2) "n3"

    3) "n2"

    我们发现 以及有数据了

    小结: 我们平时可以把aof文件定期备份 然后需要的时候 拷贝到redis下 重启即可;

    学习资料参考:《一头扎进Redis》 和  http://blog.java1234.com  感谢:小锋

  • 相关阅读:
    InterlockedIncrement函数详解
    c#事件调用
    jdk-8u281-windows-x64.exe JavaSE开发包
    安卓SDK_installer_r24.4.1-windows
    c#中@符号作用
    c#winformAPI_MFC_API
    NFC上位机未发现RFID设备
    MFC隐藏到托盘双击还原_右键退出实现方法
    win10 win+R快捷指令启动程序汇总
    CAN总线调试---节点掉线问题
  • 原文地址:https://www.cnblogs.com/pony1223/p/7565477.html
Copyright © 2011-2022 走看看