Redis

概念:

Redis是用C语言开发的一个开源的、高性能、键值对(key-value)数据库

官方提供的数据:

​ 50个并发执行100000个请求时读的速度是:110000 次每秒,写的速度是:81000 次每秒

一、Redis应用场景

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

二、下载安装

  1. 官网

  2. 中文网

  3. 下载后解压就可以直接使用

    redis.windows.conf:配置文件

    redis.cli.exe:Redis客户端

    redis.server.exe:Redis服务端

linux安装

  1. 下载tar包并解压
    wget http://download.redis.io/releases/redis-4.0.8.tar.gz
    tar -xzvf redis-4.0.8.tar.gz

  2. 安装

    cd redis-4.0.8
    make
    cd src
    make install PREFIX=/usr/local/redis
    
  3. 移动配置文件到安装目录下

    cd ../
    mkdir /usr/local/redis/etc
    mv redis.conf /usr/local/redis/etc
    
  4. 配置redis为后台启动
      vi /usr/local/redis/etc/redis.conf//将daemonize no 改成daemonize yes

  5. 将redis加入到开机启动
    vi /etc/rc.local //在里面添加内容:
    /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf (意思就是开机调用这段开启redis的命令)

  6. 开启redis
    /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf

  7. 将redis-cli,redis-server拷贝到bin下,让redis-cli指令可以在任意目录下直接使用

    cp /usr/local/redis/bin/redis-server /usr/local/bin/
    cp /usr/local/redis/bin/redis-cli /usr/local/bin/
    

三、Redis 数据结构

Redis存储的是 key-value 格式的数据

key 都是i字符串类型,value 有5 种不同的数据结构

数据类型对应的JAVA类型备注
string(字符串)String
list(列表)LinkedList可重复
set(集合)Set不可重复,无序
hash(哈希)Map
sortedset(有序集合)TreeSet不可重复,有序

四、数据操作

1. string(字符串类型)

  1. 存储

    set [key] [value];
    # 例如
    set username lisi;
    
  2. 获取

    get [key];
    # 例如
    get username; # lisi
    
  3. 删除

    del [key];
    # 例如
    del username;
    

2. hash(哈希类型)

  1. 存储

    hset [key] [field] [value]; 
    #例如
    hset user username lisi;
    hset user password 123;
    

  2. 获取

    hget [key] [filed]; # 获取 key 中 field 字段对应的值
    hgetall [key] # 获取key中所有的字段及只
    
    # 例如
    hget user username; # lisi
    hgetall user; # username=lisi  password=123
    
  3. 删除

    hdel [key] [field]; # 删除 key 中的 field 字段及其值
    # 例如
    hdel user username; # 删除 user 中的 username 字段及其值
    

3. list(列表类型)

可以添加一个元素到列表的头部(左)或尾部(右)

可以模拟队列与堆栈

  1. 添加

    lpush [key] [value]; # 将元素添加到列表头部(左)
    rpush [key] [value]; # 将元素添加到列表尾部(右)
    # 例如
    lpush name zhangsan; # 在name列表的头部(左)添加zhangsan
    rpush name lisi; # 在name列表的尾部(右)添加lisi
    
  2. 获取

    lrange [key] [start] [end] # 范围获取(start从0开始)
    # 例如
    lrange name 1 2; #
    lrange name 0 -1; # 获取name列表中的所有元素
    
  3. 删除

    lpop [key]; # 删除列表头部(最左边)的元素,并返回该元素
    rpop [key]; # 删除列表头部(最左边)的元素,并返回该元素
    # 例如
    lpop user; # zhangsan
    rpop user; # lisi
    

4. set(集合类型)

不可重复

  1. 存储

    sadd [key] [value]; 
    # 例如
    sadd name lisi;
    
  2. 获取

    smembers [key]; # 获取集合中的所有元素
    # 例如
    smembers name;
    
  3. 删除

    srem [key] [value]; # 删除集合中的某个元素
    # 例如
    srem name lisi;
    

5. sortedset(有序集合类型)

不可重复,且元素有顺序

每个元素都会关联一个double类型的分数(score)

Redis正是通过分数来为集合中的元素进行排序的。

  1. 存储

    zadd [key] [score] [value]; 
    # 例如
    zadd name 60 lisi;
    zadd name 79 zhangsan;
    
  2. 获取

    zrange [key] [start] [end] {[whthscore]}
    # 例如
    zrange name 0 -1;
    # 1)"lisi"
    # 2)"zhangsan"
    
    zrange name 0 -1 withscore;
    # 1)"lisi"
    # 2)"60"
    # 3)"zhangsan"
    # 4)"79"
    

  3. 删除

    zrem [key] [value];
    # 例如
    zrem name lisi;
    

6. 通用

keys *(pattern); # 查询所有的键(正则表达式)
type [key]; # 查询键key 对应的value 的数据类型
del key: # 删除指定的键key 及其值 value

五、Redis事务

Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:

  • 批量操作在发送 EXEC 命令前被放入队列缓存。
  • 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
  • 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

一个事务从开始到执行会经历以下三个阶段:

  • 开始事务。
  • 命令入队。
  • 执行事务

以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令:

redis 127.0.0.1:6379> MULTI   #开启事务
OK

redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED

redis 127.0.0.1:6379> GET book-name
QUEUED

redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED

redis 127.0.0.1:6379> SMEMBERS tag
QUEUED

redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
   2) "C++"
   3) "Programming"

单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

比如:

redis 127.0.0.1:7000> multi
OK
redis 127.0.0.1:7000> set a aaa
QUEUED
redis 127.0.0.1:7000> set b bbb
QUEUED
redis 127.0.0.1:7000> set c ccc
QUEUED
redis 127.0.0.1:7000> exec
1) OK
2) OK
3) OK

如果在 set b bbb 处失败,set a 已成功不会回滚,set c 还会继续执行。

Redis 事务命令

下表列出了 redis 事务的相关命令:

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

六、Redis密码

redis没有实现访问控制这个功能,但是它提供了一个轻量级的认证方式,可以编辑redis.conf配置来启用认证。

  1. 初始化Redis密码

    在配置文件中有个参数:requirepass,这个就是配置Redis访问密码的参数

    比如:requirepass test123;(PS:需要重启Redis才能生效)

    Redis的查询速度是非常快的,外部用户一秒内可以尝试多达150K个密码;所以密码尽量要长(对于DBA没有必要必须记住密码)

  2. 不重启Redis设置密码

    • 在配置文件中配置requirepass的密码(当Redis重启时依然有效)
    redis 127.0.0.1:6379> config set requirepass test123
    
    • 查询密码:
    redis 127.0.0.1:6379> config get requirepass
    
    • 会出错:(error) ERR operation not permitted
    • 密码验证:
    redis 127.0.0.1:6379> auth test123
    
    • 再次查询:
    redis 127.0.0.1:6379> config get requirepass
    # 查询结果
    1)"requirepass"
    2)"test123"
    

    PS:如果配置文件中没添加密码,那么Redis重启后,密码失效

  3. 登录有密码的Redis

    • 在登录的时候输入密码:
    redis-cli -p 6379 -a test123
    
    • 先登录后验证
    redis-cli -p 6379
    redis 127.0.0.1:6379> auth test123
    

    AUTH命令跟其他redis命令一样,是没有加密的;阻止不了攻击者在网络上窃取你的密码;

    认证层的目标是提供多一层的保护。如果防火墙或者用来保护redis的系统防御外部攻击失败的话,外部用户如果没有通过密码认证还是无法访问redis的。

七、Redis主从复制

1. 简介

主从复制,就是主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制。

Master以写为主,Slave以读为主

在这里插入图片描述

2. 用处

  • 读写分离,性能扩展
  • 容灾快速恢复

3. 配置

  • Redis集群中的配置

    由于redis的高性能,在应用中对其依赖很高,有时候一台redis服务器性能不够,需要配置redis集群。最简单的就是一台用来读,一台用来写。一般对读的需求比较大,所以可以配置一主(写)从(读)。
    本次是在本地搭建两台虚拟机分别做一主一从。
    ip为192.168.2.100为主服务器
    ip为192.168.2.101为从服务器

    1. 首先给两台服务器分别安装redis

    2. 配置主服务器

      1. 进入主服务器,打开Redis配置文件

      2. bind 127.0.0.1 这行注释或者指定ip。(注释:即所有ip都能连接)

      3. 开启守护进程:daemonize yes

      4. 设置访问密码:requirepass 123456

        PS:由于Redis性能非常高,撞库风险极大,建议线上把密码设置非常复杂,最好能在第2步中指定ip

      注意:
      当然,既然用到主从了,那说明对redis依赖非常高,还有几个参数需要根据服务器配置来设置

      • 第一个就是客户端最大连接数(maxclients),默认是10000,可根据需求更改

      • 第二个就是最大内存(maxmemory,默认不受限制,但如果有多个从服务器,建议还是设置个低于服务器内存的值)

      • 第三个是内存策略(maxmemory-policy,默认为noeviction),如果内存足够用则不用管,如果内存不够用,建议设置最近最少使用策略(LRU),默认是内存不够则报错

        # volatile-lru -> remove the key with an expire set using an LRU algorithm
        # allkeys-lru -> remove any key according to the LRU algorithm
        # volatile-random -> remove a random key with an expire set
        # allkeys-random -> remove a random key, any key
        # volatile-ttl -> remove the key with the nearest expire time (minor TTL)
        # noeviction -> don't expire at all, just return an error on write operations
        #
        # The default is:
        #
        # maxmemory-policy noeviction
        

      至此主服务器配置完毕!
      启动redis服务

      [root@localhost redis-4.0.10]# service redis start
      
  1. 配置从服务器

    前四步与主服务器配置基本一致

    1. 配置所属主服务器ip和端口

      slaveof 192.128.2.100 6379

    2. 配置所属主服务器的密码(再次强调,要将密码设置非常复杂,这里只是演示)

      masterauth 123456

    需要注意的是,从服务器通常是只读,所以要配置只读(默认是只读,不要更改即可)

    1. 配置只读

      slave-read-only yes

    2. 配置完成,启动服务

      [root@localhost redis-4.0.10]# service redis start
      
  2. 测试

    使用redis客户端或者telnet都可以
    本次使用redis客户端

    1. 进入主服务器

      进入redis客户端

      [root@localhost redis-4.0.10]# /usr/local/redis/bin/redis-cli
      

      由于设置了密码,所以需要鉴权

      127.0.0.1:6379> auth 123456
      

      设置一个值

      127.0.0.1:6379>set name zhangsan
      
    2. 进入从服务器(192.168.2.101)

      使用get命令获取name的值

      [root@localhost redis-4.0.10]# /usr/local/redis/bin/redis-cli
      127.0.0.1:6379> auth 123456
      127.0.0.1:6379> get name
      

      如果获取到了zhangsan代表配置成功
      如果在从服务器上写,则会报错,如下;

      127.0.0.1:6379> set age 11
      (error) READONLY You Can't write against a read only slave
      

    至此,redis主从复制配置完成,如果需要配置多台从服务器,可以重复第三步

  • 同一台服务器上配置主从

    • 拷贝多个redis.conf文件include
    • 开启daemonize yes
    • Pid文件名字pidfile
    • 指定端口port
    • log文件名字
    • Dump.rdb名字dbfilename
    • Appendonly 关掉或者换名字
    1. redis.conf

      daemonize yes
      appendonly no
      
    2. 创建一个ms目录,存放主从关系

    3. 拷贝redis.conf到ms目录下

      cp redis.conf ms/redis6379.conf
      cp redis.conf ms/redis6380.conf
      cp redis.conf ms/redis6381.conf
      
    4. 修改每个Redis的配置文件

      # 全部删掉在配置
      include [redis.conf的路径]
      port 6380
      pidfile /var/run/redis_6380.pid
      dbfilename dump6380.rdb
      slaveof 127.0.0.1 6379
      
    5. 启动

      redis-server ms/redis_6379.conf
      redis-server ms/redis_6380.conf
      redis-server ms/redis_6381.conf
      
    6. 客户端连接

      redis-cli -p 6379
      redis-cli -p 6380
      redis-cli -p 6381
      
    7. 查看Redis的主从复制信息(是Master还是slave)

      info replication命令:打印主从复制关系

    8. 建立主从关系

      在从机上加一行命令:

      slaveof [ip] [port]:成为某个实例的从服务器

      建议在配置文件中配置:slaveof 127.0.0.1 6379

      127.0.0.1:6380> slaveof localhost 6379
      127.0.0.1:6381> slaveof localhost 6379
      

4. 一仆二主

  1. 切入点问题:

    slave1、slave2是从头开始复制还是从切入点开始复制? —— 从头开始复制

    比如从机k4进来了,那之前的123是否也可以复制? —— 可以

5. 复制原理

  • 每次从机联通后,都会给主机发送sync指令
  • 主机立刻进行存盘操作,发送RDB文件,给从机
  • 从机收到RDB文件后,进行全盘加载
  • 之后每次主机的写操作,都会立刻发送给从机,从机执行相同的命令

6. 主-从-从

master——slaver1——slaver2

虽然slaver1对于slaver2来说是其主机,但slaver1实质上还只是一个从机,不能执行写操作

**作用:**可以有效减轻Master的写压力,去中心化降低风险,提升服务器性能

在这里插入图片描述

**风险:**风险是一旦某个Slaver宕机,后面的Slave都没法备份

7. 反客为主

当一个Master宕机后,后面的slave可以立刻升为Master,其后面的slave不用做任何修改

slaveof no one:将从机变为主机

8. 哨兵模式(sentinel)

反客为主的自动版,能够在后台监控主机是否故障,如果故障了根据投票数自动将从机转换为主机
在这里插入图片描述

  • 配置哨兵

    以上图的一仆二主模式为例

    进入redis文件夹下,新建sentinel.conf文件

    # sentinel monitor <master-name> <ip> <redis-port> <quorum>
    # 告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效
    sentinel monitor mymaster 127.0.0.1 6379 1
    
    # sentinel auth-pass <master-name> <password>
    # 设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
    
    # sentinel down-after-milliseconds <master-name> <milliseconds> 
    # 这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒
    
    # sentinel parallel-syncs <master-name> <numslaves> 
    # 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
    
    # sentinel failover-timeout <master-name> <milliseconds>
    # failover-timeout 可以用在以下这些方面:     
    # 	1. 同一个sentinel对同一个master两次failover之间的间隔时间。   
    #	2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。    
    #	3.当想要取消一个正在进行的failover所需要的时间。    
    #	4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了。
    
  • 启动哨兵

    执行

    redis-sentinel /redis/sentinel-26379.conf
    

9. 故障恢复

在这里插入图片描述

slave-priority 100:数字越低,优先级越高

slave-priority 0:永远不让该从机做主机(适用于性能极差的服务器上的Redis)

七、Redis Cluster(Redis集群)

1. Redis Cluster(Redis集群)简介

  • Redis集群实现了对Redis的水平扩容,即启动N个Redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N

  • Redis集群通过分区(partition)来提供一定程度的可用性(availability):

    即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求

  • redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;

  • redis集群是没有统一的入口的,客户端(client)连接集群的时候连接集群中的任意节点(node)即可,集群内部的节点是相互通信的(PING-PONG机制),每个节点都是一个redis实例;

  • 为了实现集群的高可用,即判断节点是否健康(能否正常使用),redis-cluster有这么一个投票容错机制:如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了(fail)。这是判断节点是否挂了的方法;

  • 那么如何判断集群是否挂了呢? -> 如果集群中任意一个节点挂了,而且该节点没有从节点(备份节点),那么这个集群就挂了。这是判断集群是否挂了的方法;

  • 那么为什么任意一个节点挂了(没有从节点)这个集群就挂了呢? -> 因为集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果。再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点挂了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作。

  • 综上所述,每个Redis集群理论上最多可以有16384个节点。

2. 集群搭建需要的环境

  1. Redis集群至少需要3个节点,因为投票容错机制要求超过半数节点认为某个节点挂了该节点才是挂了,所以2个节点无法构成集群。
  2. 要保证集群的高可用,需要每个节点都有从节点,也就是备份节点,所以Redis集群至少需要6台服务器。因为我没有那么多服务器,也启动不了那么多虚拟机,所在这里搭建的是伪分布式集群,即一台服务器虚拟运行6个redis实例,修改端口号为(7001-7006),当然实际生产环境的Redis集群搭建和这里是一样的。
  3. 安装ruby

3. 集群搭建具体步骤如下(注意要关闭防火墙)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 在usr/local目录下新建redis-cluster目录,用于存放集群节点

  2. 把redis目录下的bin目录下的所有文件复制到/usr/local/redis-cluster/redis01目录下,不用担心这里没有redis01目录,会自动创建的。操作命令如下(注意当前所在路径):

    cp -r redis/bin/ redis-cluster/redis01

  3. 删除redis01目录下的快照文件dump.rdb,rm -rf dump.rdb

    并且修改该目录下的redis.cnf文件,具体修改两处地方:

    一是端口号修改为7001,

    二是开启集群创建模式,将cluster-enabled yes 的注释打开

  4. 将redis-cluster/redis01文件复制5份到redis-cluster目录下(redis02-redis06),创建6个redis实例,模拟Redis集群的6个节点。然后将其余5个文件下的redis.conf里面的端口号分别修改为7002-7006。

  5. 接着启动所有redis节点,由于一个一个启动太麻烦了,所以在这里创建一个批量启动redis节点的脚本文件,命令为start-all.sh,文件内容如下:

    cd redis01
    ./redis-server redis.conf
    cd ..
    cd redis02
    ./redis-server redis.conf
    cd ..
    cd redis03
    ./redis-server redis.conf
    cd ..
    cd redis04
    ./redis-server redis.conf
    cd ..
    cd redis05
    ./redis-server redis.conf
    cd ..
    cd redis06
    ./redis-server redis.conf
    cd ..
    
  6. 创建好启动脚本文件之后,需要修改该脚本的权限,使之能够执行,指令如下:

    chmod +x starth-all.sh
    
  7. 执行start-all.sh脚本,启动6个redis节点

  8. ok,至此6个redis节点启动成功,接下来正式开启搭建集群,以上都是准备条件。大家不要觉得图片多看起来冗长所以觉得麻烦,其实以上步骤也就一句话的事情:创建6个redis实例(6个节点)并启动。

要搭建集群的话,需要使用一个工具(脚本文件),这个工具在redis解压文件的源代码里。因为这个工具是一个ruby脚本文件,所以这个工具的运行需要ruby的运行环境,就相当于java语言的运行需要在jvm上。所以需要安装ruby,指令如下:

yum install ruby
yum install rubygems

然后需要把ruby相关的包安装到服务器(/opt),我这里用的是redis-3.0.0.gem,大家需要注意的是:redis的版本和ruby包的版本最好保持一致。

将Ruby包安装到服务器:需要先下载再安装

gem install redis-3.0.0.gem
# gem install --local redis-3.0.0.gem
  1. 上一步中已经把ruby工具所需要的运行环境和ruby包安装好了,接下来需要把这个ruby脚本工具复制到usr/local/redis-cluster目录下。那么这个ruby脚本工具在哪里呢?之前提到过,在redis解压文件的源代码里,即redis/src目录下的redis-trib.rb文件。

  2. 将该ruby工具(redis-trib.rb)复制到redis-cluster目录下,指令如下:

    cp redis-trib.rb /usr/local/redis-cluster
    

    然后使用该脚本文件搭建集群,指令如下:

    ./redis-trib.rb create --replicas 1 47.106.219.251:7001 47.106.219.251:7002 47.106.219.251:7003 47.106.219.251:7004 47.106.219.251:7005 47.106.219.251:7006
    

    注意:此处大家应该根据自己的服务器ip输入对应的ip地址!

    中途有个地方需要手动输入yes即可

    至此,Redi集群搭建成功!大家注意最后一段文字,显示了每个节点所分配的slots(哈希槽),这里总共6个节点,其中3个是从节点,所以3个主节点分别映射了0-5460、5461-10922、10933-16383solts。

  3. 最后连接集群节点,连接任意一个即可:

    redis01/redis-cli -p 7001 -c
    

    注意:一定要加上-c,不然节点之间是无法自动跳转的!如下图可以看到,存储的数据(key-value)是均匀分配到不同的节点的:

3. Redis集群基本命令

加上两条redis集群基本命令:
1.查看当前集群信息

cluster info

2.查看集群里有多少个节点

cluster nodes

五、Redis持久化

Redis是一个内存数据库,当Redis服务端重启获取服务器重启,数据会丢失,我们可以将Redis内存中的数据持久化保存到硬盘中。

Redis持久化机制

1. RDB

默认方式,不需要配置

在一定的时间间隔内,检测key的value的变化情况,然后持久化。

  1. 编辑redis.windows.conf文件

    save 900 1		# 900秒内,如果有 1 个key的value发生了变化,就持久化
    save 300 10		# 300秒内,如果有 10 个key的value发生了变化,就持久化
    save 60 10000	# 60秒内,如果有 10000 个key的value发生了变化,就持久化
    
  2. 重启Redis服务器,并指定配置文件

    $ redis.server.exe redis.widows.conf
    

持久化后会生成一个 xxx.rdb 文件

2. AOF(不建议)

日志记录的方式,可以记录每一条命令的操作

不建议使用,影响性能

  1. 编辑redis.windows.conf文件

    appendonly no  # no:关闭AOF,yes:开启AOF
    
    # 开启AOF后配置持久化策略
    # appendfsync always  	# 每一次操作都进行一次持久化
    # appendfsync everysec	# 每个一秒进行一次持久化
    # appendfsync no	    # 不持久化
    
  2. 重启Redis服务器,并指定配置文件

    $ redis.server.exe redis.widows.conf
    

持久化后会生成一个 xxx.aof 文件

六、JAVA客户端(Jedis)

Jedis:一款Java操作Redis数据库的工具

1. 使用步骤

  1. 导入Jedis的 jar包: jedis-2.8.1.jar
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.8.1</version>
</dependency>
  1. 使用
Jedis jedis = new Jedis("localhost",6379);
jedis.set("username","list");
jedis.close();

2. 操作数据

  1. string(字符串类型)

    jedis.set("key", "value");
    jedis.get("key");
    jedis.setex(String key, int seconds, String value); // 存储key,value 并指定过期时间seconds(秒)
    
  2. hash(哈希类型)

    jedis.hset(String key, String field, String value);
    jedis.hget(String key, String field);
    jedis.hgetAll(String key) // 返回值 Map<String, String>
    
  3. list(列表类型)

    jedis.lpush(String key, String ... values); // 添加到列表头部(最左边)
    jedis.rpush(String key, String ... values); // 添加到列表尾部(最右边)
    jedis.lrange(String key, long start, long end); // 范围获取,返回值 List<String>
    jedis.lpop(String key) // 获取并删除列表头部(最左边)的元素
    jedis.rpop(String key) // 获取并删除列表尾部(最右边)的元素
    
  4. set(集合类型)

    jedis.sadd(String key, String ... value);
    jedis.smembers(String key); // 获取key中的全部元素,返回值 Set<String>
    
  5. sortedset(有续集合类型)

    jedis.zadd(String key, double score, String values);
    jedis.zadd(String key, Map<String, Double>);
    jedis.zrange(String key, long start, long end);
    

八、Jedis连接池

JedisPool jar包: commons-pool2-2.3.jar

1. 创建JedisPool连接池对象

JedisPool jedisPool = new JedisPool(config,"localhost",6379);

2. 获取Jedis连接

Jedis jedis = JedisPool.getResource();

3. 使用

4. 关闭连接

jedis.close();

//0.创建一个配置对象
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(50); // 最大活动对象个数
config.setMaxIdle(10); // 最大保持连接状态的对象个数
//1.创建Jedis连接池对象
JedisPool jedisPool = new JedisPool(config,"localhost",6379);
//2.获取连接
Jedis jedis = jedisPool.getResource();
//3. 使用
jedis.set("hehe","heihei");
//4. 关闭 归还到连接池中
jedis.close();

九、Jedis连接池工具类

package com.dahua0318.util;

import java.io.IOException;
import java.util.Properties;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * Jedis连接池工具类
* Copyright: Copyright (c) 2019 LanRu-Caifu
* 
* @ClassName: JedisUtils.java
* @Description: Jedis连接池工具类
*
* @version: v1.0.0
* @author: Administrator
 */
public class JedisUtils {

	// @Fields pool : 声明Jedis连接池对象
	private static JedisPool pool;
	
	static {
		//创建Properties属性集对象
		Properties prop = new Properties();
		try {
			//将配置文件数据加载到属性集中
           prop.load(JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//创建一个Jedis连接池配置对象
		JedisPoolConfig config = new JedisPoolConfig();
		//配置连接池的最大活动对象数     maxTotal
		config.setMaxTotal(Integer.parseInt(prop.getProperty("maxTotal")));
		//配置连接池的最大能够保持idel状态的对象数    maxIdle
		config.setMaxIdle(Integer.parseInt(prop.getProperty("maxIdle")));
		
		//创建连接池对象(连接池配置对象,主机名,端口号)
		pool = new JedisPool(config,prop.getProperty("host"),Integer.parseInt(prop.getProperty("port")));
		
	}
	
	/**
	 * 	获取Jedis连接池连接对象Jedis
	 * @return jedis Jedis
	 */
	public static Jedis getJedis() {
		return pool.getResource();
	}
	
}

十、注意

使用Redis缓存一些关系型数据库(MySQL,Oracle等)中不经常发生变化的数据。

如果数据一旦发生变化,则需要更新缓存。

例如:

​ MySQL数据库的表执行增删改的操作,需要将Redis中的缓存数据删除,重新存入。

​ 在service层对应的增删改业务操作中,将Redis缓存删除,在查询的业务操作中重新存入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值