Redis事务,集群。

Redis 安装

使用Redis cluster 搭建集群

单机Redis事务

Redis集群事务,不支持简单命令事务

 

 

一、在机器上安装VMware,使用linux centos 7系统。准备两台虚拟机。两台虚拟机都是   

CentOS ,一台 CentOS6.5 (IP:192.168.190.128),一台 CentOS(IP:192.168.190.129 

二、安装过程:

  1. 、下载并解压

cd /root/software

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

tar -zxvf redis-3.2.4.tar.gz

  1. 、编译安装

     cd redis-3.2.4

make && make install

  1. 将 redis-trib.rb 复制到 /usr/local/bin 目录下 

       cd src

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

4)、创建 Redis 节点

首先在 192.168.31.245 机器上 /root/software/redis-3.2.4 目录下创建 redis_cluster 目录;

mkdir redis_cluster

 

在 redis_cluster 目录下,创建名为7000、7001、7002的目录,并将 redis.conf 拷贝到这三个目录中

 

mkdir 7000 7001 7002

cp redis.conf redis_cluster/7000

cp redis.conf redis_cluster/7001

cp redis.conf redis_cluster/7002

 

分别修改这三个配置文件,修改如下内容

 

port  7000                                        //端口7000,7002,7003        

bind 本机ip                                       //默认ip为127.0.0.1 需要改为其

他节点机器可访问的ip 否则创建集群时无法访问对应的端口,无法创建集群

daemonize    yes                               //redis后台运行

pidfile  /var/run/redis_7000.pid          //pidfile文件对应7000,7001,7002

cluster-enabled  yes                           //开启集群  把注释#去掉

cluster-config-file  nodes_7000.conf   //集群的配置  配置文件首次启动自动生成

7000,7001,7002

cluster-node-timeout  15000                //请求超时  默认15秒,可自行设置

appendonly  yes                           //aof日志开启  有需要就开启,它会每次写操

作都记录一条日志 

接着在另外一台机器上(192.168.31.210),的操作重复以上三步,只是把目录改为7003、7004、7005,对应的配置文件也按照这个规则修改即可

5)、 启动各个节点

第一台机器上执行

redis-server redis_cluster/7000/redis.conf

redis-server redis_cluster/7001/redis.conf

redis-server redis_cluster/7002/redis.conf

 

另外一台机器上执行

redis-server redis_cluster/7003/redis.conf

redis-server redis_cluster/7004/redis.conf

redis-server redis_cluster/7005/redis.conf

  1. 检查redis启动情况

    ##一台机器
ps -ef | grep redis

root  61020    1  0 02:14 ?     00:00:01 redis-server 127.0.0.1:7000 [cluster]    

root  61024    1  0 02:14 ?     00:00:01 redis-server 127.0.0.1:7001 [cluster]    

root  61029    1  0 02:14 ?     00:00:01 redis-server 127.0.0.1:7002 [cluster]    

 

netstat -tnlp | grep redis

tcp    0   0 127.0.0.1:17000      0.0.0.0:*        LISTEN   61020/redis-server

tcp    0   0 127.0.0.1:17001      0.0.0.0:*        LISTEN   61024/redis-server

tcp    0   0 127.0.0.1:17002      0.0.0.0:*        LISTEN   61029/redis-server

tcp    0   0 127.0.0.1:7000       0.0.0.0:*        LISTEN   61020/redis-server

tcp    0   0 127.0.0.1:7001       0.0.0.0:*        LISTEN   61024/redis-server

tcp    0   0 127.0.0.1:7002       0.0.0.0:*        LISTEN      61029/redis-server

  1. 创建集群

Redis 官方提供了 redis-trib.rb 这个工具,就在解压目录的 src 目录中,第三步中已将它复制到 /usr/local/bin 目录中,可以直接在命令行中使用了。使用下面这个命令即可完成安装。

redis-trib.rb  create  --replicas  1  192.168.190.128:7000 192.168.190.128:7001  192.168.190.128:7002 192.168.190.129:7003  192.168.190.129:7004  192.168.190.129:7005

 

验证: redis-cli -h 192.168.31.245 -c -p 7002

  1. 过程中需要安装gcc编译工具,安装ruby环境。

Redis cluster的原理简单描述:

redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。

Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。所以我们在测试的时候看到set 和 get 的时候,直接跳转到了7000端口的节点。

Redis 集群会把数据存在一个 master 节点,然后在这个 master 和其对应的salve 之间进行数据同步。当读取数据时,也根据一致性哈希算法到对应的 master 节点获取数据。只有当一个master 挂掉之后,才会启动一个对应的 salve 节点,充当 master 。

需要注意的是:必须要3个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总节点数的一半时,整个集群就无法提供服务了。

 

 

 

其他redis集群方案:

   哨兵模式codis

 

Redis事务:

简单理解,可以认为redis事务是一些列redis命令的集合,并且有如下两个特点:

a)事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

b)事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

 

事务需要满足ACID原则

 

Multi exec dicard watch

命令举例:

正常执行

127.0.0.1:6379> MULTI

OK127.0.0.1:6379> SET key1 1

QUEUED127.0.0.1:6379> HSET key2 field1 1

QUEUED127.0.0.1:6379> SADD key3 1

QUEUED127.0.0.1:6379> EXEC1) OK2) (integer) 13) (integer) 1

 

EXEC 命令的回复是一个数组,数组中的每个元素都是执行事务中的命令所产生的回复。 其中,回复元素的先后顺序和命令发送的先后顺序一致。

当客户端处于事务状态时,所有传入的命令都会返回一个内容为 QUEUED 的状态回复(status reply),这些被入队的命令将在 EXEC命令被调用时执行

放弃事务

当执行 DISCARD 命令时,事务会被放弃,事务队列会被清空,并且客户端会从事务状态中退出:

127.0.0.1:6379> MULTI

OK127.0.0.1:6379> SET key1 1

QUEUED127.0.0.1:6379> DISCARD

OK127.0.0.1:6379> EXEC

(error) ERR EXEC without MULTI

 

入队错误回滚

 

127.0.0.1:6379> MULTI

OK127.0.0.1:6379> set key1 1

QUEUED127.0.0.1:6379> HSET key2 1

(error) ERR wrong number of arguments for 'hset' command127.0.0.1:6379> SADD key3 1

QUEUED127.0.0.1:6379> EXEC

(error) EXECABORT Transaction discarded because of previous errors.

对于入队错误,redis 2.6.5版本后,会记录这种错误,并且在执行EXEC的时候,报错并回滚事务中所有的命令,并且终止事务。

 

执行错误放过

 

127.0.0.1:6379> MULTI

OK127.0.0.1:6379> HSET key1 field1 1

QUEUED127.0.0.1:6379> HSET key2 field1 1

QUEUED127.0.0.1:6379> EXEC1) (error) WRONGTYPE Operation against a key holding the wrong kind of value2) (integer) 1

当遇到执行错误时,redis放过这种错误,保证事务执行完成。

这里要注意此问题,与mysql中事务不同,在redis事务遇到执行错误的时候,不会进行回滚,而是简单的放过了,并保证其他的命令正常执行。这个区别在实现业务的时候,需要自己保证逻辑符合预期。

 

使用watch命令

WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。

被 WATCH 的键会被监视,并会发觉这些键是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回空多条批量回复(null multi-bulk reply)来表示事务已经失败。

 

127.0.0.1:6379> WATCH key1

OK127.0.0.1:6379> set key1 2

OK127.0.0.1:6379> MULTI

OK127.0.0.1:6379> set key1 3

QUEUED127.0.0.1:6379> set key2 3

QUEUED127.0.0.1:6379> EXEC

(nil)

使用上面的代码, 如果在 WATCH 执行之后, EXEC 执行之前, 有其他客户端修改了 key1 的值, 那么当前客户端的事务就会失败。 程序需要做的, 就是不断重试这个操作, 直到没有发生碰撞为止。

这种形式的锁被称作乐观锁, 它是一种非常强大的锁机制。 并且因为大多数情况下, 不同的客户端会访问不同的键, 碰撞的情况一般都很少, 所以通常并不需要进行重试。

 

 

 

 

 

 

 

 

 

 

Redis 安装

使用Redis cluster 搭建集群

单机Redis事务

Redis集群事务,不支持简单命令事务

 

 

一、在机器上安装VMware,使用linux centos 7系统。准备两台虚拟机。两台虚拟机都是   

CentOS ,一台 CentOS6.5 (IP:192.168.190.128),一台 CentOS(IP:192.168.190.129 

二、安装过程:

  1. 、下载并解压

cd /root/software

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

tar -zxvf redis-3.2.4.tar.gz

  1. 、编译安装

     cd redis-3.2.4

make && make install

  1. 将 redis-trib.rb 复制到 /usr/local/bin 目录下 

       cd src

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

4)、创建 Redis 节点

首先在 192.168.31.245 机器上 /root/software/redis-3.2.4 目录下创建 redis_cluster 目录;

mkdir redis_cluster

 

在 redis_cluster 目录下,创建名为7000、7001、7002的目录,并将 redis.conf 拷贝到这三个目录中

 

mkdir 7000 7001 7002

cp redis.conf redis_cluster/7000

cp redis.conf redis_cluster/7001

cp redis.conf redis_cluster/7002

 

分别修改这三个配置文件,修改如下内容

 

port  7000                                        //端口7000,7002,7003        

bind 本机ip                                       //默认ip为127.0.0.1 需要改为其

他节点机器可访问的ip 否则创建集群时无法访问对应的端口,无法创建集群

daemonize    yes                               //redis后台运行

pidfile  /var/run/redis_7000.pid          //pidfile文件对应7000,7001,7002

cluster-enabled  yes                           //开启集群  把注释#去掉

cluster-config-file  nodes_7000.conf   //集群的配置  配置文件首次启动自动生成

7000,7001,7002

cluster-node-timeout  15000                //请求超时  默认15秒,可自行设置

appendonly  yes                           //aof日志开启  有需要就开启,它会每次写操

作都记录一条日志 

接着在另外一台机器上(192.168.31.210),的操作重复以上三步,只是把目录改为7003、7004、7005,对应的配置文件也按照这个规则修改即可

5)、 启动各个节点

第一台机器上执行

redis-server redis_cluster/7000/redis.conf

redis-server redis_cluster/7001/redis.conf

redis-server redis_cluster/7002/redis.conf

 

另外一台机器上执行

redis-server redis_cluster/7003/redis.conf

redis-server redis_cluster/7004/redis.conf

redis-server redis_cluster/7005/redis.conf

  1. 检查redis启动情况

    ##一台机器
ps -ef | grep redis

root  61020    1  0 02:14 ?     00:00:01 redis-server 127.0.0.1:7000 [cluster]    

root  61024    1  0 02:14 ?     00:00:01 redis-server 127.0.0.1:7001 [cluster]    

root  61029    1  0 02:14 ?     00:00:01 redis-server 127.0.0.1:7002 [cluster]    

 

netstat -tnlp | grep redis

tcp    0   0 127.0.0.1:17000      0.0.0.0:*        LISTEN   61020/redis-server

tcp    0   0 127.0.0.1:17001      0.0.0.0:*        LISTEN   61024/redis-server

tcp    0   0 127.0.0.1:17002      0.0.0.0:*        LISTEN   61029/redis-server

tcp    0   0 127.0.0.1:7000       0.0.0.0:*        LISTEN   61020/redis-server

tcp    0   0 127.0.0.1:7001       0.0.0.0:*        LISTEN   61024/redis-server

tcp    0   0 127.0.0.1:7002       0.0.0.0:*        LISTEN      61029/redis-server

  1. 创建集群

Redis 官方提供了 redis-trib.rb 这个工具,就在解压目录的 src 目录中,第三步中已将它复制到 /usr/local/bin 目录中,可以直接在命令行中使用了。使用下面这个命令即可完成安装。

redis-trib.rb  create  --replicas  1  192.168.190.128:7000 192.168.190.128:7001  192.168.190.128:7002 192.168.190.129:7003  192.168.190.129:7004  192.168.190.129:7005

 

验证: redis-cli -h 192.168.31.245 -c -p 7002

  1. 过程中需要安装gcc编译工具,安装ruby环境。

Redis cluster的原理简单描述:

redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。

Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。所以我们在测试的时候看到set 和 get 的时候,直接跳转到了7000端口的节点。

Redis 集群会把数据存在一个 master 节点,然后在这个 master 和其对应的salve 之间进行数据同步。当读取数据时,也根据一致性哈希算法到对应的 master 节点获取数据。只有当一个master 挂掉之后,才会启动一个对应的 salve 节点,充当 master 。

需要注意的是:必须要3个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总节点数的一半时,整个集群就无法提供服务了。

 

 

 

其他redis集群方案:

   哨兵模式codis

 

Redis事务:

简单理解,可以认为redis事务是一些列redis命令的集合,并且有如下两个特点:

a)事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

b)事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

 

事务需要满足ACID原则

 

Multi exec dicard watch

命令举例:

正常执行

127.0.0.1:6379> MULTI

OK127.0.0.1:6379> SET key1 1

QUEUED127.0.0.1:6379> HSET key2 field1 1

QUEUED127.0.0.1:6379> SADD key3 1

QUEUED127.0.0.1:6379> EXEC1) OK2) (integer) 13) (integer) 1

 

EXEC 命令的回复是一个数组,数组中的每个元素都是执行事务中的命令所产生的回复。 其中,回复元素的先后顺序和命令发送的先后顺序一致。

当客户端处于事务状态时,所有传入的命令都会返回一个内容为 QUEUED 的状态回复(status reply),这些被入队的命令将在 EXEC命令被调用时执行

放弃事务

当执行 DISCARD 命令时,事务会被放弃,事务队列会被清空,并且客户端会从事务状态中退出:

127.0.0.1:6379> MULTI

OK127.0.0.1:6379> SET key1 1

QUEUED127.0.0.1:6379> DISCARD

OK127.0.0.1:6379> EXEC

(error) ERR EXEC without MULTI

 

入队错误回滚

 

127.0.0.1:6379> MULTI

OK127.0.0.1:6379> set key1 1

QUEUED127.0.0.1:6379> HSET key2 1

(error) ERR wrong number of arguments for 'hset' command127.0.0.1:6379> SADD key3 1

QUEUED127.0.0.1:6379> EXEC

(error) EXECABORT Transaction discarded because of previous errors.

对于入队错误,redis 2.6.5版本后,会记录这种错误,并且在执行EXEC的时候,报错并回滚事务中所有的命令,并且终止事务。

 

执行错误放过

 

127.0.0.1:6379> MULTI

OK127.0.0.1:6379> HSET key1 field1 1

QUEUED127.0.0.1:6379> HSET key2 field1 1

QUEUED127.0.0.1:6379> EXEC1) (error) WRONGTYPE Operation against a key holding the wrong kind of value2) (integer) 1

当遇到执行错误时,redis放过这种错误,保证事务执行完成。

这里要注意此问题,与mysql中事务不同,在redis事务遇到执行错误的时候,不会进行回滚,而是简单的放过了,并保证其他的命令正常执行。这个区别在实现业务的时候,需要自己保证逻辑符合预期。

 

使用watch命令

WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。

被 WATCH 的键会被监视,并会发觉这些键是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回空多条批量回复(null multi-bulk reply)来表示事务已经失败。

 

127.0.0.1:6379> WATCH key1

OK127.0.0.1:6379> set key1 2

OK127.0.0.1:6379> MULTI

OK127.0.0.1:6379> set key1 3

QUEUED127.0.0.1:6379> set key2 3

QUEUED127.0.0.1:6379> EXEC

(nil)

使用上面的代码, 如果在 WATCH 执行之后, EXEC 执行之前, 有其他客户端修改了 key1 的值, 那么当前客户端的事务就会失败。 程序需要做的, 就是不断重试这个操作, 直到没有发生碰撞为止。

这种形式的锁被称作乐观锁, 它是一种非常强大的锁机制。 并且因为大多数情况下, 不同的客户端会访问不同的键, 碰撞的情况一般都很少, 所以通常并不需要进行重试。

 

 

参考博客:

https://www.cnblogs.com/kangoroo/p/7535405.html

 

 

 

 

 

 

 

 

你可能感兴趣的:(Redis事务,集群。)