生产级实践之集群搭建方案系列-Redis主从、哨兵与多主集群模式的安装配置

1. 目标

  • 介绍Redis的主从部署、哨兵部署与多主集群部署模式
  • 实现Redis主从与哨兵集群部署,以及多主集群模式的搭建配置

2. 脉络

  • 介绍Redis的所有部署模式,特点与使用场景
  • 完成Redis主从与哨兵集群部署
  • 完成Redis多主集群模式部署
  • 应用项目与集群的连接配置

3. 知行

3.1 Redis部署模式简介

Redis部署模式有多种, 包括单节点模式, 主从模式, 主从+哨兵模式, 以及集群模式。

  • Redis单节点模式

    安装简单,客户端直连, 操作简便; 不存在多节点数据同步或脑裂问题, 在开发环境中可直接采用单节点模式, 简化维护。如果应用服务规模比较小, 可以直接采用单节点单机部署。
    在这里插入图片描述

  • 主从模式

    单节点模式部署主要存在两个问题: 数据备份和数据体量较大造成的性能降低,主从模式指的是使用一个redis实例作为主机,其余的实例作为备份机, 主节点负责读写, 从节点专门负责数据的读取。

    主从同步机制: 从节点启动后, 主动向master发送SYNC命令, 主节点接收到SYNC命令后在后台保存快照, 将保存的快照文件和期间的缓存操作指令发送给从节点。

    如果具有一定数据规模和性能要求, 可以采用主从模式,
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TpFgOxn2-1585451486636)(images/165552b1609ca8e2)]

  • 哨兵模式

主从模式下, 如果主节点出现故障,从节点因为没有主节点同步而中断, 需要人工进行故障处理。Sentinel哨兵模式是Redis推出的原生高可用解决方案, 主要包括两部分, Sentinel集群和Redis主从集群。
哨兵的功能主要是监控主从节点运行是否正常, 当master主节点出现故障时, 会自动将slave从节点转化为主节点。 要求较高的稳定性和高可用性, 可采用哨兵模式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bqv0TOB1-1585451486637)(images/165552b160945a6b)]

  • 集群模式

    主从和哨兵模式虽然解决了一定的性能和数据瓶颈, 但是对于大量的写操作场景, 还是不能满足, 如果对于从节点出现故障, 哨兵模式是不会对其进行故障转移, 因此在Redis3.0版本推出了cluster集群功能, 能够有效解决这些问题。

    Cluster集群处理机制: 集群总共定义了16384个槽(slot),所有数据根据一致性哈希算法映射到某个槽中, 16384个槽根据Redis实例数量进行平均分配, 比如有A、B、C三个实例, 集群会将0-5460号槽分配给A,5461-10922号槽分配给B,10923-16383号槽分配给C。由于一致hash算法是一定的, 无论多少个redis实例,都可以将这16384个槽散列平均分配。Redis集群通过这种机制,来达到高性能和高可用性。

    在大型项目应用中,具有海量数据规模, 要求较高的稳定性和扩展性, 可以采用集群模式。
    在这里插入图片描述

3.2 Redis哨兵模式部署
3.2.1 部署规划

Redis主从部署:

20.20.50.26: Redis主节点, 端口6379

20.20.50.27: Redis从节点, 端口6379

20.20.50.28: Redis从节点, 端口6379

哨兵部署:

20.20.50.26: 哨兵节点一, 端口26379

20.20.50.27: 哨兵节点二, 端口26379

20.20.50.28: 哨兵节点三, 端口26379

3.2.2 Redis安装

先将Redis服务安装在三台节点上。

  1. 安装依赖组件

    yum -y install tcl gcc
    
  2. 下载安装包

    wget http://download.redis.io/releases/redis-4.0.2.tar.gz
    
  3. 解压

    tar -xvf redis-4.0.2.tar.gz
    
  4. 编译安装

    cd redis-4.0.2
    make
    make install
    

    如果make 错误, 可以执行make distclean 清理, 再重新make编译。

    安装成功, 可以看到以下提示:

    Hint: It's a good idea to run 'make test' ;)
        INSTALL install
        INSTALL install
        INSTALL install
        INSTALL install
        INSTALL install
    
  5. 配置

    • 复制启动脚本

      cp utils/redis_init_script /etc/init.d/redis_6379
      
    • 复制配置文件

      mkdir -p /etc/redis
      cp redis.conf /etc/redis/6379.conf
      
    • 修改配置文件:

      vi /etc/redis/6379.conf
      
    • 修改内容:

      # 后台方式运行
      daemonize yes
      # PID文件保存位置
      pidfile /var/run/redis_6379.pid
      # Redis服务监听端口
      port 6379
      # 持久化文件存储路径, 如果没有此目录, 则创建: make -p /var/redis/6379
      dir /var/redis/6379
      # 绑定IP地址, 如果要远程连接, 需要绑定外部IP地址, 可以绑定多个, 以空格分隔
      bind 127.0.0.1
      
    • 设置开机启动

      修改启动脚本:

      vi /etc/init.d/redis_6379
      

      在头部增加:

      #!/bin/sh
      # chkconfig: 2345 90 10 
      
    • 启动与关闭

      /etc/init.d/redis_6379 start
      /etc/init.d/redis_6379 stop
      
3.2.3 主从创建

这里20.20.50.26为主节点, 将20.20.50.27与20.20.50.28作为从节点, 纳入集群。

  1. 手动创建

    • 进入20.20.50.27
      执行以下命令:

      [root@localhost local]# redis-cli  -p 6379
      127.0.0.1:6379> slaveof 20.20.50.26 6379
      OK Already connected to specified master
      
    • 进入20.20.50.28
      执行相同命令, 加入集群:

      [root@localhost local]# redis-cli  -p 6379
      127.0.0.1:6379> slaveof 20.20.50.26 6379
      OK Already connected to specified master
      
    • 进入20.20.50.26主节点, 验证查看集群信息:

      [root@localhost redis-4.0.2]# redis-cli 
      127.0.0.1:6379> info replication
      # Replication
      role:master
      connected_slaves:2
      slave0:ip=20.20.50.28,port=6379,state=online,offset=2617,lag=0
      slave1:ip=20.20.50.27,port=6379,state=online,offset=2617,lag=0
      master_replid:c41563977b922b3877b4c470743efd1feb26099a
      master_replid2:0000000000000000000000000000000000000000
      master_repl_offset:2617
      second_repl_offset:-1
      repl_backlog_active:1
      repl_backlog_size:1048576
      repl_backlog_first_byte_offset:1
      repl_backlog_histlen:2617
      

      可以看到, connected_slaves显示连接的从节点数量为2, 三台节点成功组建主从集群。

  2. 配置自动创建

    通过配置方式, 自动创建, 不需每次重启后, 都执行加入命令。

     vi /etc/redis/6379.conf 
    

    增加配置:

    slaveof 20.20.50.26 6379
    
  3. 验证

    在从节点是无法写入数据:

    [root@localhost redis-4.0.2]# redis-cli -h 20.20.50.28 -p 6379
    20.20.50.28:6379> set test 123
    (error) READONLY You can't write against a read only slave.
    

    在20.20.50.26主节点, 可以写入数据:

    127.0.0.1:6379> set test 123
    OK
    

    从节点查询是否能同步数据:

    [root@localhost redis-4.0.2]# redis-cli -h 20.20.50.28 -p 6379
    20.20.50.28:6379> get test
    "123"
    
3.2.4 哨兵配置

在三台节点, 分别执行以下配置。

  1. 复制哨兵配置文件

    cp /usr/local/redis-4.0.2/sentinel.conf /etc/redis/
    
  2. 修改配置文件

    echo > /etc/redis/sentinel.conf
    vi /etc/redis/sentinel.conf
    

    增加以下内容:

    # 绑定IP地址, 注意绑定IP时,要将外部通讯IP放置前面, 否则会出现找不到sentinel节点的情况
    bind 20.20.50.26 127.0.0.1
    # 绑定监听的端口
    port 26379
    # 是否开启保护模式, 如果绑定外部IP, 需要关闭访问保护
    protected-mode no
    # 后台方式运行
    daemonize yes
    
    # sentinel监控配置
    sentinel monitor mymaster  20.20.50.26 6379 2
    sentinel down-after-milliseconds mymaster  15000
    sentinel parallel-syncs mymaster  1
    sentinel failover-timeout mymaster  30000
    
    

    配置说明:

    sentinel monitor mymaster 20.20.50.26 6379 2: Sentinel去监视一个名为redis_master的主redis实例,IP地址为20.20.50.26,端口号为6379,将这个主实例判断为失效至少需要2个 Sentinel进程的同意。

    sentinel down-after-milliseconds mymaster :指定了Sentinel认为Redis实例已经失效所需的毫秒数。当实例超过该时间没有返回PING,或者直接返回错误,那么Sentinel将这个实例标记为主观下线。

    sentinel parallel-syncs mymaster 1:指定在执行故障转移时,最多有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长。

    sentinel failover-timeout mymaster 30000:如果在该时间(ms)内未能完成failover操作,则认为该failover失败。

  3. 启动哨兵

    在三台节点分别配置完成以后, 再执行启动命令:

     redis-sentinel /etc/redis/sentinel.conf
    

    如果出现警告提示:

     WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
    

    修改:

    vi /etc/sysctl.conf
    net.core.somaxconn=32768
    sysctl -p
    
  4. 查看哨兵集群状态

    [root@localhost ~]# redis-cli  -p 26379
    127.0.0.1:26379> info sentinel
    # Sentinel
    sentinel_masters:1
    sentinel_tilt:0
    sentinel_running_scripts:0
    sentinel_scripts_queue_length:0
    sentinel_simulate_failure_flags:0
    master0:name=mymaster,status=ok,address=20.20.50.26:6379,slaves=2,sentinels=3
    

    可以看到sentinel_masters数为1, sentinels总数为3,哨兵集群搭建成功。

3.2.5 哨兵功能验证
  1. 先进入哨兵集群, 查看当前状态

    [root@localhost ~]# redis-cli  -p 26379
    127.0.0.1:26379> info sentinel
    # Sentinel
    sentinel_masters:1
    sentinel_tilt:0
    sentinel_running_scripts:0
    sentinel_scripts_queue_length:0
    sentinel_simulate_failure_flags:0
    master0:name=mymaster,status=ok,address=20.20.50.26:6379,slaves=2,sentinels=3
    
  2. 停止Redis主节点服务, 再此查看状态信息

    [root@localhost ~]# /etc/init.d/redis_6379 stop
    Stopping ...
    Waiting for Redis to shutdown ...
    Redis stopped
    

    查看哨兵集群信息(间隔数秒)

    127.0.0.1:26379> info sentinel
    # Sentinel
    sentinel_masters:1
    sentinel_tilt:0
    sentinel_running_scripts:0
    sentinel_scripts_queue_length:0
    sentinel_simulate_failure_flags:0
    master0:name=mymaster,status=ok,address=20.20.50.27:6379,slaves=2,sentinels=3
    

    可以看到, Redis主节点已经从20.20.50.26转移至20.20.50.27服务器上。

  3. 验证单个哨兵节点的有效性

    我们在哨兵配置中, sentinel monitor mymaster 20.20.50.26 6379 2 , 将哨兵投票数量设为2, 如果只存在1个哨兵节点, 是无法重新进行选主, 我们做个验证。

    • 恢复Redis主从三个节点, 正常运行

      [root@localhost ~]# /etc/init.d/redis_6379 start
      Starting Redis server...
      
    • 查看当前哨兵状态:

      127.0.0.1:26379> info sentinel
      # Sentinel
      sentinel_masters:1
      sentinel_tilt:0
      sentinel_running_scripts:0
      sentinel_scripts_queue_length:0
      sentinel_simulate_failure_flags:0
      master0:name=mymaster,status=ok,address=20.20.50.27:6379,slaves=2,sentinels=3
      

      可以看到, 当前Redis主节点为20.20.50.27。

    • 停止两个哨兵节点

      停止20.20.50.27上的哨兵服务:

      redis-cli -p 26379 shutdown
      

      停止20.20.50.28上的哨兵服务:

      redis-cli -p 26379 shutdown
      
    • 停止20.20.50.27节点上的Redis服务

      [root@localhost ~]# /etc/init.d/redis_6379 stop
      Stopping ...
      Waiting for Redis to shutdown ...
      Redis stopped
      
    • 再次查看哨兵状态

      127.0.0.1:26379> info sentinel
      # Sentinel
      sentinel_masters:1
      sentinel_tilt:0
      sentinel_running_scripts:0
      sentinel_scripts_queue_length:0
      sentinel_simulate_failure_flags:0
      master0:name=mymaster,status=sdown,address=20.20.50.27:6379,slaves=2,sentinels=1
      

      状态变为sdown, 但没有选举新的Redis主节点, 整个哨兵集群数量不够, 没有生效。

3.3 Redis集群模式部署
3.3.1 部署规划

Redis主从部署:

20.20.50.26: Redis主节点, 端口7000; Redis从节点, 端口7001。

20.20.50.27: Redis从节点, 端口7000; Redis从节点, 端口7001。

20.20.50.28: Redis从节点, 端口7000; Redis从节点, 端口7001。

3.3.2 Redis安装

参考上面3.2.2章节Redis安装, 确保Redis已成功安装。

3.3.3 Ruby安装

Redis集群创建工具需要依赖Ruby, 如果已安装, 并且版本在2.4.5以上, 可以忽略此步骤。

注意重新建立会话, 要使用ruby, 需要通过命令开启: scl enable rh-ruby24 bash

  1. 安装YUM源

     yum install -y centos-release-scl-rh
    
  2. 安装ruby2.4以上版本

     yum  -y install rh-ruby24
    
  3. scl开启

    scl enable rh-ruby24 bash
    

    如果重新建立会话, 要再次开启。

  4. 查看ruby版本

    [root@localhost src]# ruby -v
    ruby 2.4.6p354 (2019-04-01 revision 67394) [x86_64-linux]
    [root@localhost src]# gem -v
    2.6.14.4
    
  5. gen安装redis插件

    [root@localhost src]# gem install redis
    Fetching: redis-4.1.3.gem (100%)
    Successfully installed redis-4.1.3
    Parsing documentation for redis-4.1.3
    Installing ri documentation for redis-4.1.3
    Done installing documentation for redis after 1 seconds
    1 gem installed
    
3.3.4 集群安装配置
  1. 分别在三台节点上创建集群目录

    mkdir -p /usr/local/redis_cluster/7000/
    mkdir -p /usr/local/redis_cluster/7001/
    
  2. 集群配置文件

    在每台节点上创建主从两个节点的配置文件:

    vi /etc/redis/cluster-7000.conf 
    

    7000端口节点的配置内容:

    # 绑定IP, 注意改成对应不同节点的IP地址
    bind 20.20.50.26
    port 7000
    # 客户端连接密码
    requirepass Redis1234{}
    # 集群连接密码
    masterauth Redis1234{}
    # 是否后台运行
    daemonize yes
    pidfile /usr/local/redis_cluster/7000/redis.pid
    appendonly yes
    appendfilename "appendonly_7000.aof"
    dir /usr/local/redis_cluster/7000/
    dbfilename "dump_7000.rdb"
    protected-mode no
    
    cluster-enabled yes
    cluster-config-file /usr/local/redis_cluster/7000/nodes.conf
    # 集群超时时间
    cluster-node-timeout 5000
    # 表示负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用
    cluster-require-full-coverage no
    maxmemory 100mb
    # 缓存更新策略, 优先删除掉最近最不经常使用的key
    maxmemory-policy allkeys-lru
    maxclients 10000
    
    
    

    继续增加7001的配置:

    vi /etc/redis/cluster-7001.conf 
    

    配置内容:

    bind 20.20.50.26
    port 7001
    # 客户端连接密码
    requirepass Redis1234{}
    # 集群连接密码
    masterauth Redis1234{}
    # 是否后台运行
    daemonize yes
    pidfile /usr/local/redis_cluster/7001/redis.pid
    appendonly yes
    appendfilename "appendonly_7001.aof"
    dir /usr/local/redis_cluster/7001/
    dbfilename "dump_7001.rdb"
    protected-mode no
    
    cluster-enabled yes
    cluster-config-file /usr/local/redis_cluster/7001/nodes.conf
    # 集群超时时间
    cluster-node-timeout 5000
    # 表示负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用
    cluster-require-full-coverage no
    maxmemory 100mb
    # 缓存更新策略, 优先删除掉最近最不经常使用的key
    maxmemory-policy allkeys-lru
    maxclients 10000
    
  3. 启动各集群节点

    redis-server /etc/redis/cluster-7000.conf 
    redis-server /etc/redis/cluster-7001.conf 
    

    查看进程:

    [root@localhost ~]# ps -ef | grep cluster
    root      32933      1  0 00:01 ?        00:00:05 redis-server 20.20.50.26:7000 [cluster]
    root      33038      1  0 00:03 ?        00:00:04 redis-server 20.20.50.26:7001 [cluster]
    
3.3.5 集群创建
  1. 执行命令

    cd /usr/local/redis-4.0.2/src
    ./redis-trib.rb  create  --replicas  1  20.20.50.26:7000 20.20.50.26:7001  20.20.50.27:7000 20.20.50.27:7001  20.20.50.28:7000  20.20.50.28:7001
    

    如果出现不能连接创建的错误:

    [ERR] Sorry, can't connect to node 20.20.50.26:7000
    

    先确保ruby的redis插件已安装, 检查所有节点是否都已正常启动。

     gem install redis
    

    如果还是出现错误, 需要修改ruby的redis配置文件, 加上认证密码:

     vi /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/redis-4.1.3/lib/redis/client.rb
    

    修改:

    class Redis
      class Client
    
        DEFAULTS = {
          :url => lambda { ENV["REDIS_URL"] },
          :scheme => "redis",
          :host => "127.0.0.1",
          :port => 6379,
          :path => nil,
          :timeout => 5.0,
          :password => "Redis1234{}",
    

    确认password输入正确。

  2. 再次执行集群创建命令

    [root@localhost src]# ./redis-trib.rb  create  --replicas  1  20.20.50.26:7000 20.20.50.26:7001  20.20.50.27:7000 20.20.50.27:7001  20.20.50.28:7000  20.20.50.28:7001
    >>> Creating cluster
    >>> Performing hash slots allocation on 6 nodes...
    Using 3 masters:
    20.20.50.26:7000
    20.20.50.27:7000
    20.20.50.28:7000
    Adding replica 20.20.50.27:7001 to 20.20.50.26:7000
    Adding replica 20.20.50.26:7001 to 20.20.50.27:7000
    Adding replica 20.20.50.28:7001 to 20.20.50.28:7000
    M: 770036cb37f3fd9623e79b677e032488d307929e 20.20.50.26:7000
       slots:0-5460 (5461 slots) master
    S: b88106a9c1da2ccf706f0348527c5c411ce53276 20.20.50.26:7001
       replicates f75cf9009d46f462b34c917fec35c9307a0f3778
    M: f75cf9009d46f462b34c917fec35c9307a0f3778 20.20.50.27:7000
       slots:5461-10922 (5462 slots) master
    S: 82ff87e5f73422a213951467b70fbc409bc68e51 20.20.50.27:7001
       replicates 770036cb37f3fd9623e79b677e032488d307929e
    M: b3687887df3db9333c455044866dbaa21b786fc9 20.20.50.28:7000
       slots:10923-16383 (5461 slots) master
    S: 0cfa4bdcd26c5a974ef64b606452bcf70de5d7b9 20.20.50.28:7001
       replicates b3687887df3db9333c455044866dbaa21b786fc9
    Can I set the above configuration? (type 'yes' to accept): yes
    >>> Nodes configuration updated
    >>> Assign a different config epoch to each node
    >>> Sending CLUSTER MEET messages to join the cluster
    Waiting for the cluster to join....
    >>> Performing Cluster Check (using node 20.20.50.26:7000)
    M: 770036cb37f3fd9623e79b677e032488d307929e 20.20.50.26:7000
       slots:0-5460 (5461 slots) master
       1 additional replica(s)
    M: f75cf9009d46f462b34c917fec35c9307a0f3778 20.20.50.27:7000
       slots:5461-10922 (5462 slots) master
       1 additional replica(s)
    S: b88106a9c1da2ccf706f0348527c5c411ce53276 20.20.50.26:7001
       slots: (0 slots) slave
       replicates f75cf9009d46f462b34c917fec35c9307a0f3778
    S: 0cfa4bdcd26c5a974ef64b606452bcf70de5d7b9 20.20.50.28:7001
       slots: (0 slots) slave
       replicates b3687887df3db9333c455044866dbaa21b786fc9
    S: 82ff87e5f73422a213951467b70fbc409bc68e51 20.20.50.27:7001
       slots: (0 slots) slave
       replicates 770036cb37f3fd9623e79b677e032488d307929e
    M: b3687887df3db9333c455044866dbaa21b786fc9 20.20.50.28:7000
       slots:10923-16383 (5461 slots) master
       1 additional replica(s)
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    

    按提示选择yes继续处理, 可以在最后面看到所有slots分配成功的提示。

  3. 集群的信息查看

    连接到集群节点:

     redis-cli -h 20.20.50.26  -p 7000
    

    查看集群状态信息:

    20.20.50.26:7000> cluster info
    cluster_state:ok
    cluster_slots_assigned:16384
    cluster_slots_ok:16384
    cluster_slots_pfail:0
    cluster_slots_fail:0
    cluster_known_nodes:6
    cluster_size:3
    cluster_current_epoch:13
    cluster_my_epoch:10
    cluster_stats_messages_ping_sent:6837
    cluster_stats_messages_pong_sent:5196
    cluster_stats_messages_fail_sent:64
    cluster_stats_messages_auth-req_sent:5
    cluster_stats_messages_auth-ack_sent:3
    cluster_stats_messages_sent:12105
    cluster_stats_messages_ping_received:5193
    cluster_stats_messages_pong_received:5529
    cluster_stats_messages_fail_received:30
    cluster_stats_messages_auth-req_received:4
    cluster_stats_messages_auth-ack_received:2
    cluster_stats_messages_update_received:2
    cluster_stats_messages_received:10760
    
3.4 应用项目连接配置

Spring Data Redis 在1.7版本开始支持Redis的集群,如果非1.7版本,需要自己实现Redis集群的支持。这里采用Spring Data Redis版本为2.1.9.RELEASE, 可以直接支持集群使用。

  1. 修改项目配置

    修改配置文件bootstrap.yml:

    spring:
      redis:
    #    host: 127.0.0.1
    #    password:
    #    port: 6379
        # jedis 连接池配置
        jedis:
          pool:
            max-wait: 6000
            min-idle: 2
            max-idle: 8
        # 集群节点配置
        cluster:
          nodes: 20.20.50.26:7000,20.20.50.26:7001,20.20.50.27:7000,20.20.50.27:7001,20.20.50.28:7000,20.20.50.28:7001
        # 集群连接超时配置
        timeout: 2000
        # 密码认证配置
        password: 654321
    

    将原来的单节点连接配置注释, 增加集群与连接池配置。 只修改配置文件即可, 其他不用修改。

    连接缓存集群节点, 查看缓存信息

    [root@localhost ~]# redis-cli -c -h 20.20.50.26 -p 7000
    20.20.50.26:7000> auth Redis1234{}
    OK
    20.20.50.26:7000> keys *
    1) "account:warn:setting:stockId:1::1"
    

    -c 开启集群模式, 能够支持重定向操作。

4. 合理

  • 这里讲解了Redis所支持的部署模式, 并实际搭建部署了哨兵模式与多主集群模式,哨兵模式实际上是包含了主从模式的搭建,基本上是覆盖了Redis的所有部署模式。
  • 每种部署模式都有其适合的场景, 因地制宜, 合理选择, 更为简单高效的使用Redis, 当然java端的集群连接组件有很多, Spring Boot 从2.0开始, Redis的连接组件从Jedis替换为Lettuce, 不同客户端有不同的特性与实现机制,具体大家可以再去搜寻相关资料, 这里就不再赘述。

本文由mirson创作分享,如需进一步交流,请加QQ群:19310171或访问www.softart.cn

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦神-mirson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值