Redis应用

1.1 特点

  • 内存数据库,速度快,也支持数据持久化
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供List、Hash、Set、Sorted Set等多种数据类型
  • Redis支持数据的备份(master-slave)与集群(分片存储),以及拥有哨兵模式
  • 支持事务

1.2 优势

  • 性能极高- Redis能读的速度是110000次/s,写的速度81000次/s
  • 丰富的数据类型-Redis支持String、List、Hash、Set、Sorted Set等数据结构
  • 原子操作,Redis所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行(事务)
  • 丰富的特性,Redis还支持push/subscribe、通知key过期等特性

3. Redis的高并发

3.1 原理

  1. Redis是纯内存数据库,所以读取速度快
  2. Redis使用的是非阻塞IO、IO多路复用,减少了线程切换时上下文的切换和竞争
  3. Redis采用单线程模式,保证了每个操作的原子性,也减少了线程的上线文切换和竞争
  4. Redis存储结构多样化,不同的数据结构对数据存储进行了优化,加快读取速度
  5. Redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。

3.2 Redis单线程

3.2.1 原因

  1. 不需要各种锁的性能消耗
  2. 但鲜橙多进程集群方案
  3. CPU消耗

3.2.2 优劣

单进程单线程优势

  1. 代码更清晰,处理逻辑更简单。
  2. 不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能死锁而导致的性能消耗
  3. 不存在多进程或者多线程导致的切换而消耗CPU

单进程单线程弊端

  1. 无法发挥多核CPU性能,不过可以通过单机开多个实例进行完善。

3.2.2 IO 多路复用

4 Redis安装

4.1 单机版安装

安装wget工具

 yun -y install wget

下载安装包(本次安装6.0.9) 安装包地址(https://download.redis.io/releases/)

wget https://download.redis.io/releases/redis-6.0.9.tar.gz

安装gcc+c环境

yum install -y gcc-c++ autoconf automake

4.3.1 升级gcc

在编译Redis 6之前需要升级gcc的版本,默认情况下yum安装的gcc版本是4.8.5,由于版本过低,在编译期间会报错。因此在编译前需要先升级gcc

# 安装scl源
yum install -y centos-release-scl scl-utils-build
# 安装9版本的gcc、gcc-c++、gbd工具链(toolchain)
yum install -y devtoolset-9-toolchain
# 临时覆盖系统原有的gcc 引用
scl enable devtoolset-9 bash
# 检查gcc当前版本
gcc -v

成功升级到gcc 9版本

[root@localhost redis-6.0.9]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-9/root/usr --mandir=/opt/rh/devtoolset-9/root/usr/share/man --infodir=/opt/rh/devtoolset-9/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --with-default-libstdcxx-abi=gcc4-compatible --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-9.3.1-20200408/obj-x86_64-redhat-linux/isl-install --disable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)

4.3.2 预编译

tar -zxvf redis-6.0.9.tar.gz -C /usr/local/
cd  /usr/local/redis-6.0.9/
make

4.3.3 创建redis安装目录

mkdir -p /usr/local/redis
make PREFIX=/usr/local/redis/ install

4.3.4 启动redis

cd /usr/local/redis/bin

./redis-server

启动后可以看到redis显示为单节点、Port Redis应用

4.3.5 配置以守护进程的方式启动(后台启动)

  • 拷贝 6.0.9下的redis.conf bash cd redis-6.0.9/ cp redis.conf /usr/local/redis/bin/
  • 修改redis.conf
# 修改第224行
daemonize yes

再次启动

./redis-server ./redis.conf

4.3.6 配置开机启动(CentOS 7以上)

  1. 在系统服务目录中创建redis.service文件 bash vi /etc/systemd/system/redis.service写入以下内容 ``` bash [Unit] Description=redis-server After=network.target

[Service] Type=forking ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf PrivateTmp=true

[Install] WantedBy=multi-user.target

*重载系统服务*
``` bash
systemctl daemon-reload 
  1. 测试并加入开机自启
  2. 关闭redis-server systemctl stop redis.service
  3. 开启redis-server systemctl start redis.service
  4. 重启redis-server systemctl restart redis.service
  5. 查看redis-server状态 systemctl status redis.service
  6. 将服务加入开机自启 bash systemctl enable redis.service
  7. daemonize默认情况下,redis不是在后台运行的,如果需要在后台运行,把该项的值更改为yes
  8. bind 指定redis只接受来自于该ip的请求
  9. port 监听端口,默认为6379
  10. databases 设置数据库的个数,默认使用的数据库是0
  11. save 设置Redis进行数据库镜像的频率
  12. dbfilename 镜像备份文件的文件名
  13. dir 数据库镜像备份的文件放置的路径
  14. requirepass 设置客户端连接后进行其他指令前需要使用密码
  15. maxclients 限制同时连接的客户数量
  16. maxmemory 设置redis能够使用的最大内存

6. Jedis客户端

6.1 Jedis连接

  1. 添加POM依赖

    <dependencies>
       <!-- jedis 客户端-->
       <dependency>
           <groupId>redis.clients</groupId>
           <artifactId>jedis</artifactId>
           <version>3.3.0</version>
       </dependency>
    
       <!--junit test-->
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>
           <scope>test</scope>
       </dependency>
    
2. 编写连接池代码
``` java
public class jedisPoolConnectRedis {
    private static JedisPool jedisPool;
    static {
        // 创建连接池配置对象
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        //设置最大连接数,默认是8
        jedisPoolConfig.setMaxTotal(5);
        //设置最大空闲数, 默认是8
        jedisPoolConfig.setMaxIdle(5);
        //设置最小空闲数量,默认是0
        jedisPoolConfig.setMinIdle(0);
        //设置等待时间 ms
        jedisPoolConfig.setMaxWaitMillis(100);
        //初始化jedisPool对象
        GenericObjectPoolConfig poolConfig;
        jedisPool = new JedisPool(jedisPoolConfig, "192.168.21.105", 6379,
                100, "123456");
    }

    /**
     * 获取Jedis对象
     * @return
     */
    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
  1. 测试类

    public class JedisPoolTest {
    Jedis jedis = null;
    
    //建立连接
    @Before
    public void init(){
       //初始化Jedis客户端
       jedis = jedisPoolConnectRedis.getJedis();
       //身份认证,设置连接密码
       //ping pang心跳机制,监测是否连接成功
       String pong = jedis.ping();
       System.out.println("pong = " + pong);
    }
    
    @Test
    public void testJedisPool(){
       Set<String> keys =
               jedis.keys("*");
        Assert.assertNotNull(keys);
    }
    
    @After
    public void close(){
       if(null!=jedis){
           jedis.close();
       }
    }
    }
    
2. application.yml配置

3. 测试类







 

7.Redis主从环境

7.1节点资源规划

ip 角色
192.168.147.102 Master
192.168.147.103 slave1
192.168.147.104 slave2

7.2创建文件目录

mkdir -p /usr/local/redis/conf
mkdir -p /usr/local/redis/data
mkdir -p /usr/local/redis/log

7.3 创建配置文件

  • 主节点(master)
# 放行访问ip限制
bind 0.0.0.0
# 后台启动
daemonize yes
# 日志存储目录及日志文件名
logfile "/usr/local/redis/log/redis.log"
# rdb数据文件名
dbfilename dump.rdb
# aof模式开启和aof数据文件名
appendonly yes
appendfilename "appendonly.aof"
# rdb数据文件和aof数据文件的存储目录
dir /usr/local/redis/data
# 设置密码
requirepass 123456
# 从节点访问主节点密码(必须与requirepass一致)
masterauth 123456
# 从节点只读模式
replica-read-only yes
  • 从节点(salve)

在maste配置文件的基础上,最后一行增加slaveof

#  从节点属于哪个主节点
slaveof 192.168.147.102 6379

7.4 启动并验证

分别启动主节点和从节点

# 启动redis 服务
/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf  

查看主从副本信息

# redis-cli连接
 /usr/local/redis/bin/redis-cli -a 123456
# 进入redis-cli后,输入 info replication 查看slave状态
info replication

主节点redis-cli连接后,查看主节点信息

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.147.104,port=6379,state=online,offset=784,lag=1
slave1:ip=192.168.147.103,port=6379,state=online,offset=784,lag=0
master_replid:e8101cf8b0d87dfd39a9ac78f9c4b4530fa051fd
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:784
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:784
127.0.0.1:6379> 

从节点redis-cli连接后,查看从节点信息

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.147.102
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:140
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:e8101cf8b0d87dfd39a9ac78f9c4b4530fa051fd
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:140
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:126
127.0.0.1:6379> 
  • 从节点反馈的主节点信息, 表明目前主从节点通讯正常。

Redis应用

8. Redis 哨兵模式

8.1 节点资源规划

IP 角色
192.168.147.102 master
192.168.147.103 slave1
192.168.147.104 slave2

8.2 编写配置文件

三个节点分别创建sentinel.conf配置文件

# 放行所有IP限制
bind 0.0.0.0
# 进程端口号
port 26379
# 后台启动
daemonize yes
# 日志记录文件
logfile "/usr/local/redis/log/sentinel.log"
# 进程编号记录文件
pidfile /var/run/sentinel.pid
# 指示Sentinel 去监视一个名为mymaster的主服务器
sentinel monitor mymaster 192.168.147.102 6379 2
# 访问主节点的密码
sentinel auth-pass mymaster 123456
# Sentinel 认为服务器已经断线所需的毫秒数
sentinel down-after-millseconds mymaster 10000
# 若Sentinel 在该配置值内未完成failover操作,则认为本次failover 失败
sentinel failover-timeout master 180000

8.3 启动

先启动3个redis服务

/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf 

再启动3个Sentinel服务

/usr/local/redis/bin/redis-server /usr/local/redis/conf/sentinel.conf --sentinel

或使用

 /usr/local/redis/bin/redis-sentinel /usr/local/redis/conf/sentinel.conf

8.4 查看启动日志

tail -f /usr/local/redis/log/sentinel.log 
12951:X 18 May 2021 04:08:07.841 # Configuration loaded
12951:X 18 May 2021 04:08:07.843 * Increased maximum number of open files to 10032 (it was originally set to 1024).
12951:X 18 May 2021 04:08:07.845 * Running mode=sentinel, port=26379.
12951:X 18 May 2021 04:08:07.846 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
12951:X 18 May 2021 04:08:07.860 # Sentinel ID is 5ceca968240397ce918bd16d1a44dbd4d8350e59
12951:X 18 May 2021 04:08:07.861 # +monitor master mymaster 192.168.147.102 6379 quorum 2
12951:X 18 May 2021 04:08:07.865 * +slave slave 192.168.147.103:6379 192.168.147.103 6379 @ mymaster 192.168.147.102 6379
12951:X 18 May 2021 04:08:07.867 * +slave slave 192.168.147.104:6379 192.168.147.104 6379 @ mymaster 192.168.147.102 6379
12951:X 18 May 2021 04:08:44.093 * +sentinel sentinel 8115d2d6bb8a7d9d360bbc569a9ca20be36a29ac 192.168.147.103 26379 @ mymaster 192.168.147.102 6379
12951:X 18 May 2021 04:08:46.702 * +sentinel sentinel d77d049e307f7704bb3e98b5068985eafaa95a04 192.168.147.104 26379 @ mymaster 192.168.147.102 6379

Redis应用

9. 哨兵工作原理

9.1 定时任务

Sentinel内部有3个定时任务,分别是:

  • 每1秒每个Sentinel对其他Sentinel和Redis节点执行ping操作(监控)
  • 每2秒每个Sentinel通过Master节点的channel交换信息(publish/Subscribe)
  • 每10秒每个Sentinel会对Master和Slave执行info命令

9.2 主观下线

所谓主管下线(Subjectively down,简称SDOWN)指的是单个Sentinel实例对服务器做出的下线判断,即单位Sentinel任务某个服务下线(有可能是接收不到订阅,之间的网络不通等原因)。

9.3 客观下线

客观下线(Objectively Down,简称ODOWN)指的是多个Sentinel实例在对同一个服务器做出SDOWN判断,并且通过命令相互交流之后,得出的服务器下线判断,然后开启failover。

9.4 仲裁

仲裁指的是配置文件中的quorum选项

quorum的值一般设置为Sentinel个数的二分之一加1,例如3个Sentinel就设置为2。

9.5哨兵的工作原理

  1. 每秒ping
  2. 有效回复PING命令的时间超时配置文件down-after-milliseconds选项所指定的值,被认定为主观下线
  3. 确认主观下线状态
  4. 满足条件,客观下线
  5. 投票选举主节点,从节点复制数据
  6. 当主节点标记为客观下线时,INFO命令触发由10s一次改为1s一次
  7. 若没有足够数量的Sentinel同意Master已经下线,Master的客观下线状态就会被移除。若Master重新向Sentinel的Ping命令返回有效回复,Master的主观下线状态就会被移除。

Redis应用

上一篇:.net 获取客户端Ip地址


下一篇:centos防火墙