当前位置: 首页 > news >正文

redis cluster 3主3从部署方案

文章目录

  • 1 Redis Cluster 介绍
  • 1 Redis cluster 架构
  • 2 Redis cluster的工作原理
    • 2.1 数据分区
    • 2.2 集群通信
    • 2.3 集群伸缩
      • 2.3.1 集群扩容
      • 2.3.2 集群缩容
    • 2.4 故障转移
      • 2.4.1 主观下线
      • 2.4.2 客观下线
  • 3 Redis Cluster 部署架构说明
    • 3.1 部署方式介绍
    • 3.2 实战案例:基于Redis 5 以上版本的 redis cluster 部署
      • 3.2.1 范例: 查看 --cluster 选项帮助
      • 3.2.2 范例: 查看CLUSTER 指令的帮助
      • 3.2.3 创建 redis cluster集群
        • 3.2.3.1 源码编译
        • 3.2.3.2 创建配置文件目录,并添加相关配置文件
          • 3.2.3.2.1 redis.conf参数说明:
          • 3.2.3.2.2 redis.service
        • 3.2.3.2.3 kernel优化配置
        • 3.2.3.3 环境配置
        • 3.2.3.4 启动检测个节点服务
        • 3.2.3.5 初始化集群
          • 3.2.3.5.1 查看集群信息meet之前
          • 3.2.3.5.2 cluster meet ip port 所有redis实例
          • 3.2.3.5.3 查看meet后集群信息
          • 3.2.3.5.4 分配数据槽位slot(在所有规划的master实例执行)
          • 3.2.3.5.5 验证master信息
          • 3.2.3.5.6 配置从节点同步主节点数据
          • 3.2.3.5.7 集群验证
        • 3.2.3.6 方法二自带命令初始化
        • 3.2.3.6.1 查看主从状态
        • 3.2.3.6.2 验证集群状态,查看对应关系
      • 3.2.4 集群伸缩
        • 3.2.4.1 扩容
          • 3.2.4.1.1 添加新节点
          • 3.2.4.1.2 在新的master上重新分配槽位
          • 3.2.4.1.3 为新的master指定新的slave节点
        • 3.2.4.2 集群缩容
          • 3.2.4.2.1迁移要删除的master节点上面的槽位到其它master
          • 3.2.4.2.2 从集群中删除服务器
  • 4 ansible 一键部署redis cluster(3台机器,每台双实例交叉部署)
    • 4.1 目录结构
    • 4.2 使用方法
      • 4.2.1 更新 inventory.ini 和 playbook.yml 文件:
      • 4.2.2 运行 playbook 并等待集群初始化确认
      • 4.2.3 卸载
      • 4.2.4 特性功能介绍

1 Redis Cluster 介绍

使用哨兵sentinel 只能解决Redis高可用问题,实现Redis的自动故障转移,但仍然无法解决Redis Master 单节点的性能瓶颈问题
为了解决单机性能的瓶颈,提高Redis 服务整体性能,可以使用分布式集群的解决方案
早期 Redis 分布式集群部署方案:

  • 客户端分区:由客户端程序自己实现写入分配、高可用管理和故障转移等,对客户端的开发实现较为
    复杂
  • 代理服务:客户端不直接连接Redis,而先连接到代理服务,由代理服务实现相应读写分配,当前代
    理服务都是第三方实现.此方案中客户端实现无需特殊开发,实现容易,但是代理服务节点仍存有单点
    故障和性能瓶颈问题。比如:豌豆荚开发的 codis
    Redis 3.0 版本之后推出无中心架构的 Redis Cluster ,支持多个master节点并行写入和故障的自动转移
    动能.

1 Redis cluster 架构

在这里插入图片描述

Redis cluster 需要至少 3个master节点才能实现,slave节点数量不限,当然一般每个master都至少对应的
有一个slave节点

如果有三个主节点采用哈希槽 hash slot 的方式来分配16384个槽位 slot
此三个节点分别承担的slot 区间可以是如以下方式分配

节点M1 0-5460
节点M2 5461-10922
节点M3 10923-16383

2 Redis cluster的工作原理

2.1 数据分区

在这里插入图片描述

数据分区通常采取顺序分布和hash分布
在这里插入图片描述

顺序分布保障了数据的有序性,但是离散性低,可能导致某个分区的数据热度高,其他分区数据的热度
低,分区访问不均衡。(偏斜)
哈希分布也分为多种分布方式,比如区域哈希分区,一致性哈希分区等。而redis cluster采用的是虚拟
槽分区的方式。
虚拟槽分区
redis cluster设置有0~16383的槽,每个槽映射一个数据子集,通过hash函数,将数据存放在不同的槽
位中,每个集群的节点保存一部分的槽。
每个key存储时,先经过哈希函数CRC16(key)得到一个整数,然后整数与16384取余,得到槽的数值,
然后找到对应的节点,将数据存放入对应的槽中。

在这里插入图片描述

2.2 集群通信

但是寻找槽的过程并不是一次就命中的,比如上图key将要存放在14396槽中,但是并不是一下就锁定了
node3节点,可能先去询问node1,然后才访问node3。
而集群中节点之间的通信,保证了最多两次就能命中对应槽所在的节点。因为在每个节点中,都保存了
其他节点的信息,知道哪个槽由哪个节点负责。这样即使第一次访问没有命中槽,但是会通知客户端,
该槽在哪个节点,这样访问对应节点就能精准命中。
在这里插入图片描述

  1. 节点A对节点B发送一个meet操作,B返回后表示A和B之间能够进行沟通。
  2. 节点A对节点C发送meet操作,C返回后,A和C之间也能进行沟通。
  3. 然后B根据对A的了解,就能找到C,B和C之间也建立了联系。
  4. 直到所有节点都能建立联系。
    这样每个节点都能互相知道对方负责哪些槽。

2.3 集群伸缩

集群并不是建立之后,节点数就固定不变的,也会有新的节点加入集群或者集群中的节点下线,这就是
集群的扩容和缩容。但是由于集群节点和槽息息相关,所以集群的伸缩也对应了槽和数据的迁移

在这里插入图片描述

2.3.1 集群扩容

当有新的节点准备好加入集群时,这个新的节点还是孤立节点,加入有两种方式。一个是通过集群节点
执行命令来和孤立节点握手,另一个则是使用脚本来添加节点

  1. cluster_node_ip:port: cluster meet ip port new_node_ip:port
  2. redis-trib.rb add-node new_node_ip:port cluster_node_ip:port
    通常这个新的节点有两种身份,要么作为主节点,要么作为从节点:
  • 主节点:分摊槽和数据
  • 从节点:作故障转移备份
    在这里插入图片描述

2.3.2 集群缩容

在这里插入图片描述

2.4 故障转移

除了手动下线节点外,也会面对突发故障。下面提到的主要是主节点的故障,因为从节点的故障并不影
响主节点工作,对应的主节点只会记住自己哪个从节点下线了,并将信息发送给其他节点。故障的从节
点重连后,继续官复原职,复制主节点的数据。
只有主节点才需要进行故障转移。在之前学习主从复制时,我们需要使用redis sentinel来实现故障转
移。而redis cluster则不需要redis sentinel,其自身就具备了故障转移功能。
根据前面我们了解到,节点之间是会进行通信的,节点之间通过ping/pong交互消息,所以借此就能发
现故障。集群节点发现故障同样是有主观下线和客观下线的

集群同样具备了自动转移故障的功能,和哨兵有些类似,在进行客观下线之后,就开始准备让故障节点
的从节点“上任”了。
首先是进行资格检查,只有具备资格的从节点才能参加选举:

  • 故障节点的所有从节点检查和故障主节点之间的断线时间
  • 超过cluster-node-timeout * cluster-slave-validati-factor(默认10)则取消选举资格
    然后是准备选举顺序,不同偏移量的节点,参与选举的顺位不同。offset最大的slave节点,选举顺位最
    高,最优先选举。而offset较低的slave节点,要延迟选举。

当有从节点参加选举后,主节点收到信息就开始投票。偏移量最大的节点,优先参与选举就更大可能获
得最多的票数,称为主节点。

在这里插入图片描述

当有从节点参加选举后,主节点收到信息就开始投票。偏移量最大的节点,优先参与选举就更大可能获
得最多的票数,称为主节点。

当从节点走马上任变成主节点之后,就要开始进行替换主节点:

  1. 让该slave节点执行slaveof no one变为master节点
  2. 将故障节点负责的槽分配给该节点
  3. 向集群中其他节点广播Pong消息,表明已完成故障转移
  4. 故障节点重启后,会成为new_master的slave节点
    在这里插入图片描述

2.4.1 主观下线

在这里插入图片描述

对于每个节点有一个故障列表,故障列表维护了当前节点接收到的其他所有节点的信息。当半数以上的
持有槽的主节点都标记某个节点主观下线,就会尝试客观下线。

2.4.2 客观下线

在这里插入图片描述

3 Redis Cluster 部署架构说明

测试环境:3台服务器,每台服务器启动6379和6380两个redis 服务实例,适用于测试环境
在这里插入图片描述

生产环境:6台服务器,分别是三组master/slave,适用于生产环境
在这里插入图片描述

#集群节点
10.0.0.8
10.0.0.18
10.0.0.28
10.0.0.38
10.0.0.48
10.0.0.58
#预留服务器扩展使用
10.0.0.68
10.0.0.78

3.1 部署方式介绍

redis cluster 有多种部署方法

  • 原生命令安装,理解Redis Cluster架构,生产环境不使用
  • 官方工具安装,高效、准确,生产环境可以使用
  • 自主研发,可以实现可视化的自动化部署

3.2 实战案例:基于Redis 5 以上版本的 redis cluster 部署

官方文档:https://redis.io/topics/cluster-tutorial
redis cluster 相关命令

3.2.1 范例: 查看 --cluster 选项帮助

redis-cli --cluster help
Cluster Manager Commands:create         host1:port1 ... hostN:portN--cluster-replicas <arg>check         host:port--cluster-search-multiple-ownersinfo           host:portfix           host:port--cluster-search-multiple-ownersreshard       host:port--cluster-from <arg>--cluster-to <arg>--cluster-slots <arg>--cluster-yes--cluster-timeout <arg>--cluster-pipeline <arg>--cluster-replacerebalance     host:port--cluster-weight <node1=w1...nodeN=wN>--cluster-use-empty-masters--cluster-timeout <arg>--cluster-simulate--cluster-pipeline <arg>--cluster-threshold <arg>--cluster-replaceadd-node       new_host:new_port existing_host:existing_port--cluster-slave--cluster-master-id <arg>del-node       host:port node_idcall           host:port command arg arg .. argset-timeout   host:port millisecondsimport         host:port--cluster-from <arg>--cluster-copy--cluster-replacehelp           
For check, fix, reshard, del-node, set-timeout you can specify the host and port 
of any working node in the cluster.

3.2.2 范例: 查看CLUSTER 指令的帮助

redis-cli CLUSTER HELP
1) CLUSTER <subcommand> arg arg ... arg. Subcommands are:
2) ADDSLOTS <slot> [slot ...] -- Assign slots to current node. 
3) BUMPEPOCH -- Advance the cluster config epoch.
4) COUNT-failure-reports <node-id> -- Return number of failure reports for
<node-id>.
5) COUNTKEYSINSLOT <slot> - Return the number of keys in <slot>.
6) DELSLOTS <slot> [slot ...] -- Delete slots information from current node. 
7) FAILOVER [force|takeover] -- Promote current replica node to being a master.
8) FORGET <node-id> -- Remove a node from the cluster.
9) GETKEYSINSLOT <slot> <count> -- Return key names stored by current node in a 
slot.
10) FLUSHSLOTS -- Delete current node own slots information.
11) INFO - Return onformation about the cluster.
12) KEYSLOT <key> -- Return the hash slot for <key>.
13) MEET <ip> <port> [bus-port] -- Connect nodes into a working cluster.
14) MYID -- Return the node id.
15) NODES -- Return cluster configuration seen by node. Output format:
16)     <id> <ip:port> <flags> <master> <pings> <pongs> <epoch> <link> <slot> 
... <slot>
17) REPLICATE <node-id> -- Configure current node as replica to <node-id>.
18) RESET [hard|soft] -- Reset current node (default: soft).
19) SET-config-epoch <epoch> - Set config epoch of current node.
20) SETSLOT <slot> (importing|migrating|stable|node <node-id>) -- Set slot 
state.
21) REPLICAS <node-id> -- Return <node-id> replicas.
22) SLOTS -- Return information about slots range mappings. Each range is made 
of:
23)     start, end, master and replicas IP addresses, ports and ids

3.2.3 创建 redis cluster集群

在这里插入图片描述

每个Redis 节点采用相同的相同的Redis版本、相同的密码、硬件配置、时间同步
所有Redis服务器必须没有任何数据
准备三台主机,地址如下:

10.0.0.129
10.0.0.130
10.0.0.131

3.2.3.1 源码编译
  • 三主三从是cluster ha的最小要求,每个节点部署两个redis实例即一个为master,一个为其他节点master的slave,以增加容错可靠行,避免同一节点两个实例都为主。生产环境如果资源允许建议每个实例部署在单独的主机上。
  • Master实例使用7001端口,Slave实例使用8002,便于管理和查看
  • 关闭redis存储功能一级opensips目前只用到了它的缓存功能,暂不需要数据持久保存,禁用rdb、aof
  • 每个redis实例需要设置密码鉴权(并且符合一定的安全复杂度)、最大使用内存、超出最大内存的清理策略建议为allkeys-lru、最大客户端连接数限制
    两个实例实现方式:第一种通过指定不通的配置文件区分;第二种部署多个运行目录,比如redis-7001,redis-8002此种方式不能使用软连接,为了统一管理生产cluster多实例部署采用了方式一
  • /data挂载单独的磁盘用于数据存储
    下载redis6.2源码包
    官网地址:https://download.redis.io/releases/redis-6.2.2.tar.gz
cd /usr/local/src   ### 上传源码到此目录
Shell>tar xfv redis-6.2.2.tar.gz   ### 解压
Shell>cd redis-6.2.2
Shell>make -j 2 PREFIX=/usr/local/redis install ## 指定安装目录编译并安装
3.2.3.2 创建配置文件目录,并添加相关配置文件
Shell>mkdir -pv /usr/local/redis/{etc,deps} ## 默认安装目录只有bin
Shell>mkdir -pv /usr/local/redis/etc/{7001,8002}#不同实例配置文件放在端口号命名的目录下
Shell>mkdir -pv /data/redis/{7001,8002}/{data,log} #创建数据目录
Shell>cp deps/hiredis/hiredis.h /usr/local/redis/deps/  ## 拷贝hiredis.h
Shell>cp -r /usr/local/src/redis-6.2.2/*.conf /usr/local/redis/etc  ## 拷贝配置文件
Shell>cp /usr/local/redis/etc/redis.conf{,.ori}  ## 备份原始配置
Shell>cp /usr/local/redis/etc/sentinel.conf{,.ori}  ### 备份哨兵配置
Shell>cp /usr/local/redis/etc/redis.conf /usr/local/redis/etc/7001/redis.conf

egrep -v “#|$” /usr/local/redis/etc/7001/redis.conf
## 提供redis7001配置文件,其他剩余节点参考此节点配置,红色标注为实例间不同配置或者重点关注配置 bind 0.0.0.0 requirepass 123456 masterauth 123456 port 7001 dir
/data/redis/7001/data logfile /data/redis/7001/log/redis.log pidfile
/usr/local/redis/etc/7001/redis.pid cluster-enabled yes
cluster-config-file nodes-7001.conf cluster-node-timeout 5000
appendonly no protected-mode yes tcp-backlog 511 timeout 0
tcp-keepalive 300 daemonize yes loglevel notice databases 16
always-show-logo no set-proc-title yes proc-title-template “{title}
{listen-addr} {server-mode}” save “” stop-writes-on-bgsave-error yes
rdbcompression yes rdbchecksum yes dbfilename dump.rdb
rdb-del-sync-files no replica-serve-stale-data yes replica-read-only
yes repl-diskless-sync no repl-diskless-sync-delay 5
repl-diskless-load disabled repl-disable-tcp-nodelay no
replica-priority 100 acllog-max-len 128 maxclients 10000 maxmemory
10485760kb maxmemory-policy allkeys-lru lazyfree-lazy-eviction no
lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush
no lazyfree-lazy-user-del no lazyfree-lazy-user-flush no oom-score-adj
no oom-score-adj-values 0 200 800 disable-thp yes appendfilename
“appendonly.aof” appendfsync everysec no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
aof-load-truncated yes aof-use-rdb-preamble yes lua-time-limit 5000
slowlog-log-slower-than 10000 slowlog-max-len 128
latency-monitor-threshold 0 notify-keyspace-events “”
hash-max-ziplist-entries 512 hash-max-ziplist-value 64
list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries
512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64
hll-sparse-max-bytes 3000 stream-node-max-bytes 4096
stream-node-max-entries 100 activerehashing yes
client-output-buffer-limit normal 0 0 0 client-output-buffer-limit
replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz
10 dynamic-hz yes aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes jemalloc-bg-thread yes

3.2.3.2.1 redis.conf参数说明:
  • 集群相关:
    cluster-enabled yes ## 开启集群模式
    cluster-config-file nodes-7001.conf ## 集群配置信息
    cluster-node-timeout 15000 ## 集群探活超时时间单位毫秒
  • 安全相关
    masterauth xxx ### slave连接master用到的密码
    requirepass xxx ### 客户端连接master用到的密码,6.x还支持acl
    maxclients 10000 ### 客户端最大连接数
    maxmemory 10485760kb ### redis使用的最大内存,如果是同一节点部署多个实例需要考虑每个实例的内存
    maxmemory-policy allkeys-lru ###当redis使用的内存大于maxmemory,回收逻辑所有keys采用LRU算法
  • 持久相关
    save “” ##关闭rbd写盘
    appendonly no ##关闭aof写盘
  • 8002实例不同配置
##shell>sed -r 's@7001@8002@g' /usr/local/redis/etc/7001/redis.conf > /usr/local/redis/etc/8002/redis.conf

打包部署文件到另外集群机器

for i in $(seq 130 131);do scp -r /usr/local/redis 10.0.0.${i}:/tmp/; echo "------------";done
3.2.3.2.2 redis.service
cat /lib/systemd/system/redis*
[Unit]
Description=Redis persistent key-value database
After=network.target[Service]
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/etc/7001/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
LimitNOFILE=1000000[Install]
WantedBy=multi-user.target[Unit]
Description=Redis persistent key-value database
After=network.target[Service]
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/etc/8002/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
LimitNOFILE=1000000[Install]
WantedBy=multi-user.target
3.2.3.2.3 kernel优化配置
echo "* - nofile 65535" >> /etc/security/limits.conf 
echo "net.core.somaxconn = 10240" >> /etc/sysctl.conf 
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf 
sysctl -p
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.local
chmod +x /etc/rc.d/rc.local

存储系统中的块优化
在存储系统中,数据通常以固定大小的块(blocks)为单位进行读写操作。如果数据被划分为很多小块(比如4KB),那么每次读写都需要处理大量的元数据和管理操作,可能会导致性能开销增加。因此,有些存储系统会采取块优化策略,比如将多个小块合并成一个大块,以减少管理开销和提高读写效率。
类比 Transparent Huge Pages (THP)

  • THP 背景
    :内存页表是操作系统管理内存地址和物理内存对应关系的结构。通常,Linux 系统使用 4KB 的小内存页。如果程序使用大量内存,这会导致大量的内存页表项,从而增加 CPU 的工作量(尤其是 TLB 缓存未命中的情况)。THP 是一种优化,通过将多个 4KB 小页合并为 2MB 或更大的大页,减少页表项的数量,进而减少页表管理的开销,提高内存访问性能。
  • 与块优化的相似点

    a.减少管理开销:两者的主要目的都是通过减少小块的管理开销来提升系统性能。存储系统中减少对小块的操作,而内存管理中减少小页的管理。
    b.性能提升:在存储系统中,块优化可以减少磁盘I/O操作的次数,提高数据吞吐量;在内存中,使用 THP 则减少了 TLB 未命中的几率,提高了 CPU 内存访问的效率。
    为什么禁用 THP?
    虽然 THP 理论上是一种优化,但在一些高性能应用中(如 Redis、数据库等),THP 的大页分配和碎片整理反而会带来额外的性能损耗,特别是在动态分配和整理大页时,可能会导致长时间的卡顿或性能抖动。因此,类似于存储系统中在某些场景下不使用大块优化,Redis 官方也推荐禁用 THP,以保持内存管理的稳定性和性能可预测性。
    总结
    THP 和块级优化的原理确实类似,都是通过合并小单位来减少系统的管理开销和性能损耗。但在特定应用场景下,禁用这类优化策略(如禁用 THP)可能会带来更好的性能表现。
3.2.3.3 环境配置

主机名

hostnamectl set-hostname redis1;exec bash
hostnamectl set-hostname redis2;exec bash
hostnamectl set-hostname redis3;exec bash

本地主机名解析

cat >> /etc/hosts <<EOF
10.0.0.129 xxx redis-n1 cluster-n1
10.0.0.130 xxx redis-n2 cluster-n2
10.0.0.131 xxx redis-n3 cluster-n3
EOF

时间同步

ntpdate ntp.aliyun.com 

添加环境变量

shell>cp -r /tmp/redis /usr/local/redis-6.2.2
Shell>cd /usr/local
Shell>ln -sv redis-6.2.2 redis  ##创建软连接
Shell> echo 'export PATH=/usr/local/redis/bin:$PATH' > /etc/profile.d/redis.sh ##导入到环境变量
Shell>source /etc/profile
3.2.3.4 启动检测个节点服务
systemctl enable --now  redis7001 redis8002
systemctl is-active  redis7001 redis8002
active
active
netstat -tnpl | grep redis  ### 查看实例端口是否正常监听,如果没有查看日志/data/redis/7001/log/redis.log
  • 7001,8002对外提供服务
  • 17001,18002 集群内部事务通信
  • 以上并不能说明已经运行为集群模式,只是申明支持(cluster enalbe=yes),需要相关配置后才能运行为cluster
  • 请确保三个节点上的所有redis实例正常启动
3.2.3.5 初始化集群
  • 默认有两种配置方式:第一种通过redis server内置命令cluster subcommand完成上述三个部分;第二种通过redis client工具redis-cli --cluster完成
  • 服务端内置命令可以理解cluster形成的过程,操作相对繁琐并且要登录到至少一半的实例上(主要是slave上);客户端工具命令不需要关心过程傻瓜式创建,速度比较快不需要登录到每一个实例,支撑一键生成。为了更好的理解redis cluster这里我使用第一种方式进行集群配置。
    #加入集群(登录任意一个redis实例,这里以10.0.0.129:7001说明)
Shell>/usr/local/redis/bin/redis-cli -h 10.135.81.33 -p 7001
Redis>auth xxx  ### 输入requirepass 指定的密码
3.2.3.5.1 查看集群信息meet之前
10.135.81.33:7001>cluster info   ### 
cluster_state:fail    ## 因为slot没有分配完所以状态是失败的
cluster_slots_assigned:0  ## 集群已分配的slot,目前是0
cluster_slots_ok:0   
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:1  ## meet一个增加1
cluster_size:0
cluster_current_epoch:0  ## 版本
cluster_my_epoch:0
cluster_stats_messages_sent:0
cluster_stats_messages_received:0查看集群信息meet之前
3.2.3.5.2 cluster meet ip port 所有redis实例
10.135.81.33:7001>cluster meet 10.135.81.34 7001
10.135.81.33:7001>cluster meet 10.135.81.35 7001
10.135.81.33:7001>cluster meet 10.135.81.33 8002
10.135.81.33:7001>cluster meet 10.135.81.34 8002
10.135.81.33:7001>cluster meet 10.135.81.34 8002
3.2.3.5.3 查看meet后集群信息
10.135.81.33:7001> cluster info
cluster_state:fail  ##没有分配完16384个槽位,状态依旧是fail
cluster_slots_assigned:0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6   ## 三主三存
cluster_size:0
cluster_current_epoch:4
cluster_my_epoch:1
cluster_stats_messages_ping_sent:108
cluster_stats_messages_pong_sent:122
cluster_stats_messages_meet_sent:5
cluster_stats_messages_sent:235
cluster_stats_messages_ping_received:122
cluster_stats_messages_pong_received:113
cluster_stats_messages_received:235
3.2.3.5.4 分配数据槽位slot(在所有规划的master实例执行)
##cluster addslots 槽位,一个槽位只能分配一个节点,16384个槽位必须分配完,不同节点不能冲突,按节点规划进行分配##
Shell>redis-cli -h 10.135.81.33 -p 7001 -a "xxxxx" cluster addslots {0..5461} 
Shell>redis-cli -h 10.135.81.34 -p 7001 -a "xxxxx" cluster addslots {5462..10922} 
Shell>redis-cli -h 10.135.81.35 -p 7001 -a "xxxxx" cluster addslots {10923..16383} 
3.2.3.5.5 验证master信息
##登录任意redis节点查看集群信息,如果不考虑mater的HA,那么到此步骤cluster分片就算配置完成###
10.135.81.33:7001> cluster info
cluster_state:ok   ## 集群状态ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:1
cluster_current_epoch:5
cluster_my_epoch:1
cluster_stats_messages_ping_sent:1052
cluster_stats_messages_pong_sent:1021
cluster_stats_messages_meet_sent:5
cluster_stats_messages_sent:2078
cluster_stats_messages_ping_received:1021
cluster_stats_messages_pong_received:1057
cluster_stats_messages_received:2078
3.2.3.5.6 配置从节点同步主节点数据

配置主从说白了就是mater的ha,mater只解决了数据分布读写,但并没有解决集群的高可用,加入其中一个master实例关掉,那么在这个mater上的slot key都不能读写。主从主要解决当master故障备用节点提升为master依旧能提供服务的问题,需要在所有的slave节点进行操作。

cluster nodes查看集群成员关系,默认没有配置主从前都认为自己是master,并且有些实例分配到了slot,有些master并没有分配到slot,这些没有分配到slot的实例就是我们用来作为slave角色来同步master的,因为在写此文档之前已经部署完成,这里暂时省略,这步主要是查看规划成为master角色的实例id,后面配置使用

###cluster replicate masterid ##
Shell>redis-cli -h 10.135.81.33 -p 8002 ###登录所有规划为slave节点的实例
Shell>auth xxxx
10.135.81.33:8002>cluster nodes   ### 查看主节点id
10.135.81.33:8002>cluster replicate xxxx ## 按规划应为10.135.81.35:7001实例的id
## 按照上述方式 登录其他从节点完成复制配置最终结果如下###
10.135.81.33:7001>cluster nodes

在这里插入图片描述

结果说明:

  • 530xxxx824d表示实例在集群内的id
  • Myself: 表示登录的当前实例
  • Master: 表示实例角色为master
  • Slave xxxx: 表示实例角色为salve,xxx表示对应的master id是什么
3.2.3.5.7 集群验证

集群状态检查

Shell>redis-cli -a ‘xxxx’ --cluster check 10.135.81.33:7001 ### 任意一个实例

在这里插入图片描述

测试key的分配

Shell>redis-cli -c -h 10.0.0.129 -p 7001 ## -c使用智能客户端支持moved
Shell>auth xxxx
Shell>set k1 v1  ## 设置一个key名字为k1 值为 v1
Shell>set k2 v2
Shell>set k3 v3
Shell>cluster keyslot k1  ## 查看k1落在哪个槽位,其实可以使用CRC(key)/16384
Shell>cluster keyslot k2
Shell>cluster keyslot k3

在这里插入图片描述

3.2.3.6 方法二自带命令初始化
#命令redis-cli的选项 --cluster-replicas 1 表示每个master对应一个slave节点
redis-cli --cluster create 10.0.0.129:7001 10.0.0.129:8002 10.0.0.130:7001 10.0.0.130:8002 10.0.0.131:7001 10.0.0.131:8002 --cluster-replicas 1 -a 123456 
Warning: Using a password with '-a' or '-u' option on the command line interface 
may not be safe.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 10.0.0.38:6379 to 10.0.0.8:6379
Adding replica 10.0.0.48:6379 to 10.0.0.18:6379
Adding replica 10.0.0.58:6379 to 10.0.0.28:6379
......

免交操作如下:

redis-cli --cluster create 10.0.0.129:7001 10.0.0.129:8002 10.0.0.130:7001 10.0.0.130:8002 10.0.0.131:7001 10.0.0.131:8002 --cluster-replicas 1 -a 123456 --cluster-yes
3.2.3.6.1 查看主从状态

在这里插入图片描述

3.2.3.6.2 验证集群状态,查看对应关系

在这里插入图片描述

3.2.4 集群伸缩

3.2.4.1 扩容

扩容适用场景:
当前客户量激增,现有的Redis cluster架构已经无法满足越来越高的并发访问请求,为解决此问题,新购
置两台服务器,要求将其动态添加到现有集群,但不能影响业务的正常访问。
注意: 生产环境一般建议master节点为奇数个,比如:3,5,7,以防止脑裂现象
在这里插入图片描述

3.2.4.1.1 添加新节点
#将一台新的主机10.0.0.68加入集群,以下示例中10.0.0.58可以是任意存在的集群节点
[root@redis-node1 ~]#redis-cli -a 123456 --cluster add-node 10.0.0.68:6379 <当前
任意集群节点>:6379
#观察到该节点已经加入成功,但此节点上没有slot位,也无从节点,而且新的节点是master
[root@redis-node1 ~]#redis-cli -a 123456 --cluster info 10.0.0.8:6379
Warning: Using a password with '-a' or '-u' option on the command line interface 
may not be safe.
10.0.0.8:6379 (cb028b83...) -> 6672 keys | 5461 slots | 1 slaves.
10.0.0.68:6379 (d6e2eca6...) -> 0 keys | 0 slots | 0 slaves.
10.0.0.48:6379 (d04e524d...) -> 6679 keys | 5462 slots | 1 slaves.
10.0.0.28:6379 (d34da866...) -> 6649 keys | 5461 slots | 1 slaves.
[OK] 20000 keys in 5 masters.
1.22 keys per slot on average.
[root@redis-node1 ~]#redis-cli -a 123456 --cluster check 10.0.0.8:6379
3.2.4.1.2 在新的master上重新分配槽位

新的node节点加到集群之后,默认是master节点,但是没有slots,需要重新分配,否则没有槽位将无法访

注意: 重新分配槽位需要清空数据,所以需要先备份数据,扩展后再恢复数据

计算16384/总节点数槽位、新的masterID、从原有哪几个节点分担槽点

redis-cli -a 123456 --cluster reshard <当前任意集群节点>:6379 … How many
slots do you want to move (from 1 to 16384)?4096 #新分配多少个槽位
=16384/master个数 What is the receiving node ID? d6e2eca6b338b717923f64866bd31d42e52edc98 #新的 master的ID Please enter
all the source node IDs. Type ‘all’ to use all the nodes as source
nodes for the hash slots. Type ‘done’ once you entered all the source
nodes IDs. Source node #1: all #输入all,将哪些源主机的槽位分配给新的节点,all是自动在所有的redis
node选择划分,如果是从redis cluster删除某个主机可以使用此方式将指定主机上的槽位全部移动到别的redis主机

3.2.4.1.3 为新的master指定新的slave节点

方法1:在新加节点到集群时,直接将之设置为slave

redis-cli -a 123456 --cluster add-node 10.0.0.78:6379 <任意集群节点>:6379 --
cluster-slave --cluster-master-id d6e2eca6b338b717923f64866bd31d42e52edc98

方法2:先将新节点加入集群,再修改为slave为新的master添加slave节点

[root@redis-node1 ~]#redis-cli -h 10.0.0.78 -p 6379 -a 123456 #登录到新添加节点
10.0.0.78:6380> CLUSTER NODES #查看当前集群节点,找到目标master 的ID
10.0.0.78:6380> CLUSTER REPLICATE 886338acd50c3015be68a760502b239f4509881c #将其设
置slave,命令格式为cluster replicate MASTERID
10.0.0.78:6380> CLUSTER NODES #再次查看集群节点状态,验证节点是否已经更改为指定master 的
slave
3.2.4.2 集群缩容

缩容适用场景:
随着业务萎缩用户量下降明显,和领导商量决定将现有Redis集群的8台主机中下线两台主机挪做它用,缩容
后性能仍能满足当前业务需求
删除节点过程:
扩容时是先添加node到集群,然后再分配槽位,而缩容时的操作相反,是先将被要删除的node上的槽
位迁移到集群中的其他node上,然后 才能再将其从集群中删除,如果一个node上的槽位没有被完全迁
移空,删除该node时也会提示有数据出错导致无法删除。
在这里插入图片描述

3.2.4.2.1迁移要删除的master节点上面的槽位到其它master

注意: 被迁移Redis master源服务器必须保证没有数据,否则迁移报错并会被强制中断。
取之于民,还之于民(多出来的4096不能直接写,因为移动目标只能操作对象只能是一个,所以移3次每次移到不同对象,槽位为多出来4096/现在主节点)

redis-cli -a 123456 --cluster reshard 10.0.0.18:6379
.....
How many slots do you want to move (from 1 to 16384)? 1356 #共4096/3分别给其它三个
master节点
3.2.4.2.2 从集群中删除服务器

上面步骤完成后,槽位已经迁移走,但是节点仍然还属于集群成员,因此还需从集群删除该节点
注意: 删除服务器前,必须清除主机上面的槽位,否则会删除主机失败

4 ansible 一键部署redis cluster(3台机器,每台双实例交叉部署)

项目地址如下:
https://gitee.com/song-yao/remote-shell-script-backup
https://github.com/songyao199681/ansible-redis-cluster

4.1 目录结构

tree ansible-redis-cluster/
ansible-redis-cluster/
├── ansible.cfg
├── playbooks
│   ├── inventory.ini
│   ├── playbook.yml
│   └── uninstall.yml
├── README.md
└── roles└── redis_cluster├── defaults├── files│   └── redis-6.2.2.tar.gz├── handlers│   └── main.yml├── hell├── meta├── tasks│   └── main.yml├── templates│   ├── redis.conf.j2│   └── redis.service.j2└── vars└── main.yml

4.2 使用方法

4.2.1 更新 inventory.ini 和 playbook.yml 文件:

cat ansible-redis-cluster/playbooks/inventory.ini
[redis_servers]
server1 ansible_host=10.0.0.129
server2 ansible_host=10.0.0.130
server3 ansible_host=10.0.0.131

4.2.2 运行 playbook 并等待集群初始化确认

cd ansible-redis-cluster/playbooks/
ansible-playbook -i inventory.ini playbook.yml

在这里插入图片描述

在这里插入图片描述

4.2.3 卸载

ansible-playbook -i inventory.ini uninstall.yml

在这里插入图片描述

4.2.4 特性功能介绍

  1. 安装时初始化支持确认
  2. 自动确定是否从本地、外网拉包
  3. 仅server1执行安装编译依赖、编译安装
  4. 修改相关配置文件触发重启
  5. 卸载前确认

相关文章:

redis cluster 3主3从部署方案

文章目录 1 Redis Cluster 介绍1 Redis cluster 架构2 Redis cluster的工作原理2.1 数据分区2.2 集群通信2.3 集群伸缩2.3.1 集群扩容2.3.2 集群缩容 2.4 故障转移2.4.1 主观下线2.4.2 客观下线 3 Redis Cluster 部署架构说明3.1 部署方式介绍3.2 实战案例&#xff1a;基于Redi…...

前端学习笔记之文件下载(1.0)

因为要用到这样一个场景&#xff0c;需要下载系统的使用教程&#xff0c;所以在前端项目中就提供了一个能够下载系统教程的一个按钮&#xff0c;供使用者进行下载。 所以就试着写一下这个功能&#xff0c;以一个demo的形式进行演示&#xff0c;在学习的过程中也发现了中文路径…...

从技术视角看AI在Facebook全球化中的作用

在全球化日益加深的今天&#xff0c;人工智能&#xff08;AI&#xff09;作为一种变革性技术&#xff0c;正在深刻影响全球互联网巨头的发展方向。Facebook作为全球最大的社交媒体平台之一&#xff0c;正通过AI技术突破语言、文化和技术的障碍&#xff0c;推动全球化战略的实现…...

Web 表单开发全解析:从基础到高级掌握 HTML 表单设计

文章目录 前言一、什么是 Web 表单?二、表单元素详解总结前言 在现代 Web 开发中,表单 是用户与后端服务交互的重要桥梁。无论是用户登录、注册、搜索,还是提交反馈,表单都无处不在。在本文中,我们将从基础入手,全面解析表单的核心知识点,并通过示例带你轻松掌握表单开…...

Milvus 2.5:全文检索上线,标量过滤提速,易用性再突破!

01. 概览 我们很高兴为大家带来 Milvus 2.5 最新版本的介绍。 在 Milvus 2.5 里&#xff0c;最重要的一个更新是我们带来了“全新”的全文检索能力&#xff0c;之所以说“全新”主要是基于以下两点&#xff1a; 第一&#xff0c;对于全文检索基于的 BM25 算法&#xff0c;我们采…...

【webrtc】 mediasoup中m77的IntervalBudget及其在AlrDetector的应用

IntervalBudget 用于带宽控制和流量整形 mediasoup中m77 代码的IntervalBudget ,版本比较老IntervalBudget 在特定时间间隔内的比特预算管理,从而实现带宽控制和流量整形。 一。 pacedsender 执行周期: 下一次执行的时间的动态可变的 int64_t PacedSender::TimeUntilNextPr…...

AI数据分析工具(二)

豆包-免费 优点 强大的数据处理能力&#xff1a; 豆包能够与Excel无缝集成&#xff0c;支持多种数据类型的导入&#xff0c;包括文本、数字、日期等&#xff0c;使得数据整理和分析变得更加便捷。豆包提供了丰富的数据处理功能&#xff0c;如数据去重、填充缺失值、转换格式等…...

小米路由mini刷PDCN教程补充

花了10天帮助一个网友解决小米路由刷PDCN做打印服务器失败的过程&#xff0c;经历颇多。特别把中间的一些坑写出来&#xff0c;希望大家不要遇到。 首先网上好多教程写的都不错&#xff0c;很适合小白。推荐如下&#xff1a; 刷breed和PDCN方法&#xff1a; 小米路由器mini刷…...

[巅峰极客 2021]签到

[巅峰极客 2021]签到 给了我们好多表情&#xff0c;真的是一脸懵逼 注意给我们的关键词 GAME 现在还不知道是什么意思我们去试着解开一下 用这个emoji表情解密器&#xff0c;这里我找了好久才找到一个 emoji-aes 这里的Key值就是GAME 运行后出现flag NSSCTF{10ve_4nd_Peace…...

详解SpringCloud集成Camunda7.19实现工作流审批(二)

本章将分享的是camunda流程设计器--Camunda Modeler的基本使用&#xff08;对应camunda版本是7.19&#xff09;&#xff0c;包括bpmn流程图画法&#xff0c;各种控件使用以及一些日常业务场景的流程图的实现 参考资料&#xff1a; Camunda BPMN 基础组件-CSDN博客 Camunda: Exe…...

Matlab学习笔记

Magic Traits 文件读取 fid fopen(fn,rt);out fscanf(fid,spec,inf);fclose(fid);2. 读取数据 fid fopen(fn,rt); out textscan(fid,spec);运算篇 fprintf(" xxx %d",a)&#xff0c;当a为数组时&#xff0c;会输出数组数目行&#xff0c;每行是一个元素相关文…...

Hexo博客在多个设备同步

title: ‘Hexo博客在多个设备同步’ date: 2024-11-28 19:08:08 categories: Hexo教程 cover: /img/cover4.jpg description: ‘实现Hexo博客在不同的设备上都可以使用和上传’ 博客链接1 &#xff1a;Hexo搭建博客的多终端同步问题 博客链接2:Hexo博客多台电脑设备同步管理 …...

淘宝Vision Pro:革新购物体验的沉浸式未来

引言 简要介绍淘宝Vision Pro版的背景,包括它在美区AppStore的发布及WWDC上的展示。阐述本文的目的:为读者提供一个全面的功能概览与设计背后的思考。设计原则 列出并简要解释5条设计原则(熟悉、直观、真实、实用、易用)。说明这些原则如何指导整个产品设计过程。核心功能详…...

公链开发中的技术实现路径:构建高效、安全的去中心化网络

区块链技术作为数字经济的重要组成部分&#xff0c;公链&#xff08;Public Chain&#xff09;是其核心架构之一。公链作为去中心化的数字账本&#xff0c;不仅承载着去中心化应用&#xff08;DApp&#xff09;的运行&#xff0c;还确保了交易的透明、安全性。随着区块链技术的…...

mac上的建议xftp 工具

mac上的建议xftp 工具 最近使用mac比较频繁了&#xff0c;但是第一次重度使用mac里面有很多的工具都是新的&#xff0c;有的window版本的工具无法使用。 xftp 的平替 Cyberduck 从它的官网上下载是免费的&#xff0c;但是如果使用 Apple store 要花费198呢。这不就剩下一大笔…...

Android 使用Charles抓包显示Unknown

最近开发的一个功能需要抓包验证一下网络请求的结果。 但是在配置完Charles的证书代理等设置后&#xff0c;抓包时显示Unknown。 在网上查了半天资料和文章&#xff0c;最终解决了问题。 以下是在调试抓包环境中遇到的一些问题和解决方法。 1、手机证书的安装 Charles在Mac…...

C++设计模式:桥接模式(Bridge)

什么是桥接模式&#xff1f; 桥接模式&#xff08;Bridge Pattern&#xff09;是一个用来解耦的设计模式&#xff0c;它将抽象层和实现层分离开&#xff0c;让它们可以独立变化。用最简单的话来说&#xff0c;就是让你能够改变抽象的功能和具体的实现&#xff0c;而不需要修改…...

spark3.x之后时间格式数据偶发报错org.apache.spark.SparkUpgradeException

3.x之后如果你去处理2.x生成的时间字符串数据&#xff0c;很容易遇到一个问题 Error operating ExecuteStatement: org.apache.spark.SparkUpgradeException: You may get a different result due to the upgrading of Spark 3.0: Fail to parse 20200725__cb90fcc3_8006_46…...

spring boot框架漏洞复现

spring - java开源框架有五种 Spring MVC、SpringBoot、SpringFramework、SpringSecurity、SpringCloud spring boot版本 版本1: 直接就在根下 / 版本2:根下的必须目录 /actuator/ 端口:9093 spring boot搭建 1:直接下载源码打包 2:运行编译好的jar包:actuator-testb…...

下载安装Android Studio

&#xff08;一&#xff09;Android Studio下载地址 https://developer.android.google.cn/studio 滑动到 点击下载文档 打开新网页 切换到english ![](https://i-blog.csdnimg.cn/direct/b7052b434f9d4418b9d56c66cdd59fae.png 等待一会&#xff0c;出现 点同意后&#xff0…...

三、计算机视觉_08YOLO目标检测

0、前言 YOLO作为目前CV领域的扛把子&#xff0c;分类、检测等任务样样精通&#xff0c;本文将基于两个小案例&#xff0c;用YOLO做检测任务&#xff0c;看看效果如何 1、对图片内容做检测 假设我有一张名为picture.jpeg的图片&#xff0c;其内容如下 我将图片和代码放到了同…...

uniapp关闭sourceMap的生成,提高编译、生产打包速度

警告信息&#xff1a;[警告⚠] packageF\components\mpvue-echarts\echarts.min.js 文件体积超过 500KB&#xff0c;已跳过压缩以及 ES6 转 ES5 的处理&#xff0c;手机端使用过大的js库影响性能。 遇到问题&#xff1a;由于微信小程序引入了mpvue-echarts\echarts.min.js&…...

uniapp首页样式,实现菜单导航结构

实现菜单导航结构 1.导入字体图标库需要的文件 2.修改引用路径iconfont.css 3.导入到App.vue中 <style>import url(./static/font/iconfont.css); </style>导航区域代码 VUE代码 <template><view class"home"><!-- 导航区域 --><…...

uniapp-vue2引用了vue-inset-loader插件编译小程序报错

报错信息 Error: Vue packages version mismatch: - vue3.2.45 (D:\qjy-myApp\admin-app\node_modules\vue\index.js) - vue-template-compiler2.7.16 (D:\qjy-myApp\admin-app\node_modules\vue-template-compiler\package.json) This may cause things to work incorrectly.…...

Git命令大全(超详细)

Git 是一个分布式版本控制系统&#xff0c;用于跟踪计算机文件的更改&#xff0c;并协调多个用户之间的工作。下面是一份较为详细的 Git 命令大全&#xff0c;涵盖了从初始化仓库到日常使用中常见的操作。 1. 初始化与配置 设置用户信息: git config --global user.name &quo…...

【机器学习】机器学习学习笔记 - 监督学习 - 逻辑回归分类朴素贝叶斯分类支持向量机 SVM (可分类、可回归) - 04

逻辑回归分类 import numpy as np from sklearn import linear_modelX np.array([[4, 7], [3.5, 8], [3.1, 6.2], [0.5, 1], [1, 2], [1.2, 1.9], [6, 2], [5.7, 1.5], [5.4, 2.2]]) y np.array([0, 0, 0, 1, 1, 1, 2, 2, 2])# 逻辑回归分类器 # solver&#xff1a;求解器&a…...

常见的数据结构---数组、链表、栈的深入剖析

目录 一、数组&#xff08;Array&#xff09; 二、链表&#xff08;Linked List&#xff09; 三、栈&#xff08;Stack&#xff09; 四、总结 数据结构是算法的基石&#xff0c;是程序设计的核心基础。不同的数据结构适用于不同的场景和需求&#xff0c;选择合适的数据结构能…...

前端开发:构建高质量用户体验的全方位指南(含实际案例与示例)

前端开发&#xff1a;构建高质量用户体验的全方位指南&#xff08;含实际案例与示例&#xff09; 在当今数字化时代&#xff0c;前端技术不仅是网页和应用的门面&#xff0c;更是连接用户与数字世界的桥梁。一个高质量的前端开发项目不仅能够提升用户体验&#xff08;UX&#…...

Istio_05_Istio架构

Istio_05_Istio架构 ArchitectureControl PlanePilotCitadelGalley Data PlaneSidecarIstio-proxyPilot-agentMetadta Exchange Ambient Architecture 如: Istio的架构(控制面、数据面) Gateway: Istio数据面的出/入口网关 Gateway分为: Ingress-gateway、Egress-gateway外部访…...

MongoDB集群分片安装部署手册

文章目录 一、集群规划1.1 集群安装规划1.2 端口规划1.3 目录创建 二、mongodb安装&#xff08;三台均需要操作&#xff09;2.1 下载、解压2.2 配置环境变量 三、mongodb组件配置3.1 配置config server的副本集3.1.1 config配置文件3.1.2 config server启动3.1.3 初始化config …...

网站网页直播怎么做的/广告推广赚钱

4-3 AutoGraph的使用规范 文章目录4-3 AutoGraph的使用规范一&#xff0c;Autograph编码规范总结二&#xff0c;Autograph编码规范解析有三种计算图的构建方式&#xff1a;静态计算图&#xff0c;动态计算图&#xff0c;以及Autograph。 TensorFlow 2.0主要使用的是动态计算图…...

微博秀 wordpress/企业网站建设报价表

java内存区域是java虚拟机在执行java程序的时候会把它所管理的内存进行划分不同的数据区域。但是java内存模型是为了屏蔽各种硬件和操作系统的内存访问的差异&#xff0c;已实现java程序在不同的操作系统中都能达到一致的访问效果Java内存区域线程共享区&#xff1a;堆&#xf…...

手机搭建网站教程视频教程/网络广告策划方案范文

DNS查找时间 可以使用的工具 $ dig www.baidu.com $ traceroute www.baidu.com 最小化应用使用的专有域名的数量 如果子域名数量上升至两位数&#xff0c;我们需要仔细考虑这方面的优化了冷启动时不必要链接的域名 对于后续的子域名&#xff0c;尝试更早的进行DNS解析&#x…...

福州企业网站建站系统/外贸推广代理

1.返回引用&#xff0c;使其可以连续调用 2.参数使用引用传递 3.分配内存前先释放自身已有的空间 4.判断是否与自身同一个实例 5.考虑申请内存时内存不足的情况 class CMyStringPrim { public:CMyStringPrim(char * pData NULL){if(pData nullptr){m_pData new char[1];m_p…...

godaddy中文网站开发/深圳网站公司排名

主题模型 主题模型这样理解一篇文章的生成过程&#xff1a; 1、 确定文章的K个主题。 2、 重复选择K个主题之一&#xff0c;按主题-词语概率生成词语。 3、 所有词语组成文章。 这里可以看到&#xff0c;主题模型仅仅考虑词语的数量&#xff0c;不考…...

电话号码查询企业/关键词seo深圳

哈喽大家好&#xff0c;我是尚妹~6月15日&#xff0c;在ES和BLG的比赛中出现了非常戏剧性的一幕&#xff1a;ES的打野Wei忘记带惩戒&#xff01;而ES和裁判交涉重开未果&#xff0c;双方保持原BP进入游戏。比赛的结果大家也都知道了&#xff0c;首局的时候ES因为没有打野&#…...