一、MySQL集群
1、mysql集群原理
MySQL-MMM是Master-MasterReplicationManagerforMySQL(mysql主主復(fù)制管理器)的簡(jiǎn)稱,是Google的開源項(xiàng)目。
(Perl腳本)。MMM基于MySQL Replication做的擴(kuò)展架構(gòu),主要用來監(jiān)控mysql主主復(fù)制并做失敗轉(zhuǎn)移。其原理是將真實(shí)數(shù)據(jù)庫節(jié)點(diǎn)的IP(RIP)映射為虛擬IP(VIP)集。mysql-mmm的監(jiān)管端會(huì)提供多個(gè)虛擬IP(VIP),包括一個(gè)可寫VIP,多個(gè)可讀VIP,通過監(jiān)管的管理,這些IP會(huì)綁定在可用mysql之上,當(dāng)某一臺(tái)mysql宕機(jī)時(shí),監(jiān)管會(huì)將VIP 遷移至其他mysql。在整個(gè)監(jiān)管過程中,需要在mysql中添加相關(guān)授權(quán)用戶,以便讓mysql可以支持監(jiān)理機(jī)的維護(hù)。授權(quán)的用戶包括一個(gè)mmm_monitor用戶和一個(gè)mmm_agent用戶,如果想使用mmm的備份工具則還要添加一個(gè)mmm_tools用戶。
MHA(MasterHighAvailability)目前在MySQL高可用方面是一個(gè)相對(duì)成熟的解決方案,由日本DeNA公司youshimaton(現(xiàn)就職于Facebook公司)開發(fā),是一套優(yōu)秀的作為MySQL高可用性環(huán)境下故障切換和主從提升的高可用軟件。在MySQL故障切換過程中,MHA能做到在0~30秒之內(nèi)自動(dòng)完成數(shù)據(jù)庫的故障切換操作(以2019年的眼光來說太慢了),并且在進(jìn)行故障切換的過程中,MHA能在最大程度上保證數(shù)據(jù)的一致性,以達(dá)到真正意義上的高可用。
InnoDBCluster支持自動(dòng)Failover、強(qiáng)一致性、讀寫分離、讀庫高可用、讀請(qǐng)求負(fù)載均衡,橫向擴(kuò)展的特性,是比較完備的一套方案。但是部署起來復(fù)雜,想要解決router 單點(diǎn)問題好需要新增組件,如沒有其他更好的方案可考慮該方案。InnoDBCluster主要由MySQLShell、MySQLRouter和MySQL服務(wù)器集群組成,三者協(xié)同工作,共同為MySQL提供完整的高可用性解決方案。MySQLShell對(duì)管理人員提供管理接口,可以很方便的對(duì)集群進(jìn)行配置和管理,MySQLRouter可以根據(jù)部署的集群狀況自動(dòng)的初始化,是客戶端連接實(shí)例。如果有節(jié)點(diǎn)down機(jī),集群會(huì)自動(dòng)更新配置。集群包含單點(diǎn)寫入和多點(diǎn)寫入兩種模式。在單主模式下,如果主節(jié)點(diǎn)down掉,從節(jié)點(diǎn)自動(dòng)替換上來,MySQLRouter會(huì)自動(dòng)探測(cè),并將客戶端連接到新節(jié)點(diǎn)。
2、Docker安裝模擬MySQL主從復(fù)制集群
1、下載mysql鏡像
2、創(chuàng)建Master實(shí)例并啟動(dòng)
dockerrun-p3307:3306--namemysql-master\-v/mydata/mysql/master/log:/var/log/mysql\
-v/mydata/mysql/master/data:/var/lib/mysql\
-v/mydata/mysql/master/conf:/etc/mysql\
-eMYSQL_ROOT_PASSWORD=root\
-dmysql:5.7
參數(shù)說明
-p3307:3306:將容器的3306端口映射到主機(jī)的3307端口
-v/mydata/mysql/master/conf:/etc/mysql:將配置文件夾掛在到主機(jī)
-v/mydata/mysql/master/log:/var/log/mysql:將日志文件夾掛載到主機(jī)
-v/mydata/mysql/master/data:/var/lib/mysql/:將配置文件夾掛載到主機(jī)-eMYSQL_ROOT_PASSWORD=root:初始化root用戶的密碼
修改master基本配置
vim/mydata/mysql/master/conf/my.cnf
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SETcollation_connection=utf8_unicode_ci'
init_connect='SETNAMESutf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
注意:skip-name-resolve一定要加,不然連接mysql會(huì)超級(jí)慢
添加master主從復(fù)制部分配置server_id=1
log-bin=mysql-bin
read-only=0
binlog-do-db=zhenyanmall_ums
binlog-do-db=zhenyanmall_pms
binlog-do-db=zhenyanmall_oms
binlog-do-db=zhenyanmall_sms
binlog-do-db=zhenyanmall_wms
binlog-do-db=zhenyanmall_admin
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
重啟 master
3、創(chuàng)建 Slave 實(shí)例并啟動(dòng)
docker run -p 3317:3306 --name mysql-slaver-01 \ -v /mydata/mysql/slaver/log:/var/log/mysql \ -v /mydata/mysql/slaver/data:/var/lib/mysql \ -v /mydata/mysql/slaver/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORD=root \ -d mysql:5.7
修改 slave 基本配置
vim /mydata/mysql/slaver/conf/my.cnf
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci' init_connect='SET NAMES utf8' character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
添加 master 主從復(fù)制部分配置
server_id=2
log-bin=mysql-bin
read-only=1
binlog-do-db=zhenyanmall_ums
binlog-do-db=zhenyanmall_pms
binlog-do-db=zhenyanmall_oms
binlog-do-db=zhenyanmall_sms
binlog-do-db=zhenyanmall_wms
binlog-do-db=zhenyanmall_admin
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
重啟 slaver
4、為 master 授權(quán)用戶來同步數(shù)據(jù)
1、進(jìn)入 master 容器
docker exec -it mysql /bin/bash
2、進(jìn)入 mysql 內(nèi)部 (mysql –uroot -p)
1)、授權(quán) root 可以遠(yuǎn)程訪問( 主從無關(guān),為了方便我們遠(yuǎn)程連接 mysql)
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
flush privileges;
2)、添加用來同步的用戶
GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by '123456';
3、查看 master 狀態(tài)
show master status\G;
5、配置 slaver 同步 master 數(shù)據(jù)
1、進(jìn)入 slaver 容器
docker exec -it mysql-slaver-01 /bin/bash
2、進(jìn)入 mysql 內(nèi)部(mysql –uroot -p)
1)、授權(quán) root 可以遠(yuǎn)程訪問( 主從無關(guān),為了方便我們遠(yuǎn)程連接 mysql)
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;flush privileges;
2)、設(shè)置主庫連接
change master to master_host='mysql-master.zhenyanmall',master_user='backup',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=0,master_port=3306;
3)、啟動(dòng)從庫同步
start slave;
4)、查看從庫狀態(tài)
show slave status\G;
至此主從配置完成;
總結(jié):
1)、主從數(shù)據(jù)庫在自己配置文件中聲明需要同步哪個(gè)數(shù)據(jù)庫,忽略哪個(gè)數(shù)據(jù)庫等信息。并且 server-id 不能一樣
2)、主庫授權(quán)某個(gè)賬號(hào)密碼來同步自己的數(shù)據(jù)
3)、從庫使用這個(gè)賬號(hào)密碼連接主庫來同步數(shù)據(jù)
測(cè)試:
在主庫里面創(chuàng)建表,添加、修改、刪除數(shù)據(jù),
從庫同步主庫的操作
3、MyCat 或者 ShardingSphere
前面測(cè)試了數(shù)據(jù)庫的主從同步問題,但是不能解決單表性能問題,所以要對(duì)數(shù)據(jù)進(jìn)行分片存儲(chǔ),每個(gè)mysql只存一片數(shù)據(jù),進(jìn)行分庫分表.
設(shè)置一個(gè)自增主鍵,第一個(gè)服務(wù)器設(shè)置自增id開始是1,每次步長(zhǎng)是2,第二個(gè)服務(wù)器是從2增長(zhǎng),每次步長(zhǎng)也是2,所以服務(wù)器1存的是1,3,5,所有的數(shù)據(jù)都是奇數(shù)列,服務(wù)器2存的是2,4,6,所有的數(shù)據(jù)都是偶數(shù)列,以后要查哪個(gè)去相應(yīng)的節(jié)點(diǎn)里面進(jìn)行查詢即可。但是這種方式不好維護(hù),最終也沒有人使用這種方式。
使用分庫分表需要使用一些中間件,比如mycat和 ShardingSphere.
shardingSphere: http://shardingsphere.apache.org/index_zh.html
auto_increment_offset: 1 從幾開始增長(zhǎng)
auto_increment_increment: 2 每次的步長(zhǎng)
1、下載安裝 Sharding-Proxy
鏡像方式
docker pull apache/sharding-proxy docker run -d -v /mydata/sharding-proxy/conf:/opt/sharding-proxy/conf -v /mydata/sharding-proxy/lib:/opt/sharding-proxy/lib --env PORT=3308 -p13308:3308 apache/sharding-proxy:latest
壓縮包下載
https://shardingsphere.apache.org/document/current/cn/downloads/
2、配置數(shù)據(jù)分片+讀寫分離
config-mallshard.yaml
schemaName: sharding_db
dataSources:
ds0:
url: jdbc:mysql://192.168.56.10:3307/ds0
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 65
ds0_slave0:
url: jdbc:mysql://192.168.56.10:3317/ds0
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 65
ds1:
url: jdbc:mysql://192.168.56.10:3307/ds1
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 65
ds1_slave0:
url: jdbc:mysql://192.168.56.10:3317/ds1
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 65
shardingRule:
tables:
t_order:
actualDataNodes: ds${0..1}.t_order${0..1}
databaseStrategy:
inline:
shardingColumn: user_id
algorithmExpression: ds${user_id % 2}
tableStrategy:
inline:
shardingColumn: order_id
algorithmExpression: t_order${order_id % 2}
keyGenerator:
type: SNOWFLAKE
column: order_id
t_order_item:
actualDataNodes: ds${0..1}.t_order_item${0..1}
databaseStrategy:
inline:
shardingColumn: user_id
algorithmExpression: ds${user_id % 2}
tableStrategy:
inline:
shardingColumn: order_id
algorithmExpression: t_order_item${order_id % 2}
keyGenerator:
type: SNOWFLAKE
column: order_item_id
bindingTables: - t_order,t_order_item
broadcastTables: - t_config
defaultDataSourceName: ds0
defaultTableStrategy:
none:
masterSlaveRules:
ms_ds0:
masterDataSourceName: ds0
slaveDataSourceNames: - ds0_slave0
loadBalanceAlgorithmType: ROUND_ROBIN
ms_ds1:
masterDataSourceName: ds1
slaveDataSourceNames: - ds1_slave0
loadBalanceAlgorithmType: ROUND_ROBIN
創(chuàng)建測(cè)試表
CREATE TABLE `t_order` (
`order_id` bigint(20) NOT NULL, `user_id` int(11) NOT NULL, `status` varchar(50) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `t_order_item` (
`order_item_id` bigint(20) NOT NULL, `order_id` bigint(20) NOT NULL, `user_id` int(11) NOT NULL, `content` varchar(255) COLLATE utf8_bin DEFAULT NULL, `status` varchar(50) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`order_item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
3、server.yaml 文件
authentication:
users:
root:
password: root
sharding:
password: sharding
authorizedSchemas: sharding_db
4、k8s 有狀態(tài)服務(wù)部署
可以使用 kubesphere,快速搭建 MySQL 環(huán)境。
? 有狀態(tài)服務(wù)抽取配置為 ConfigMap
? 有狀態(tài)服務(wù)必須使用 pvc 持久化數(shù)據(jù)
? 服務(wù)集群內(nèi)訪問使用 DNS 提供的穩(wěn)定域名
六、Redis 集群
1、redis 集群形式
1、數(shù)據(jù)分區(qū)方案
1、客戶端分區(qū)
客戶端分區(qū)方案 的代表為 Redis Sharding,Redis Sharding 是 Redis Cluster 出來之前,業(yè)界普遍使用的 Redis 多實(shí)例集群 方法。Java 的 Redis 客戶端驅(qū)動(dòng)庫 Jedis,支持 RedisSharding 功能,即 ShardedJedis 以及 結(jié)合緩存池 的 ShardedJedisPool。
優(yōu)點(diǎn)
不使用 第三方中間件,分區(qū)邏輯 可控,配置 簡(jiǎn)單,節(jié)點(diǎn)之間無關(guān)聯(lián),容易 線性擴(kuò)展,靈活性強(qiáng)。
缺點(diǎn)
客戶端 無法 動(dòng)態(tài)增刪 服務(wù)節(jié)點(diǎn),客戶端需要自行維護(hù) 分發(fā)邏輯,客戶端之間 無連接共享,會(huì)造成 連接浪費(fèi)。
2、代理分區(qū)
代理分區(qū)常用方案有 Twemproxy 和 Codis。
3、redis-cluster
2、高可用方式
1、Sentinel( 哨兵機(jī)制)支持高可用
前面介紹了主從機(jī)制,但是從運(yùn)維角度來看,主節(jié)點(diǎn)出現(xiàn)了問題我們還需要通過人工干預(yù)的方式把從節(jié)點(diǎn)設(shè)為主節(jié)點(diǎn),還要通知應(yīng)用程序更新主節(jié)點(diǎn)地址,這種方式非常繁瑣笨重, 而且主節(jié)點(diǎn)的讀寫能力都十分有限,有沒有較好的辦法解決這兩個(gè)問題,哨兵機(jī)制就是針對(duì)第
一個(gè)問題的有效解決方案,第二個(gè)問題則有賴于集群!哨兵的作用就是監(jiān)控 Redis 系統(tǒng)的運(yùn)行狀況,其功能主要是包括以下三個(gè):
? 監(jiān)控(Monitoring): 哨兵(sentinel) 會(huì)不斷地檢查你的 Master 和 Slave 是否運(yùn)作正常。
? 提醒(Notification): 當(dāng)被監(jiān)控的某個(gè) Redis 出現(xiàn)問題時(shí), 哨兵(sentinel) 可以通過 API向管理員或者其他應(yīng)用程序發(fā)送通知。
? 自動(dòng)故障遷移(Automatic failover): 當(dāng)主數(shù)據(jù)庫出現(xiàn)故障時(shí)自動(dòng)將從數(shù)據(jù)庫轉(zhuǎn)換為主數(shù)據(jù)庫。
哨兵的原理
Redis 哨兵的三個(gè)定時(shí)任務(wù),Redis 哨兵判定一個(gè) Redis 節(jié)點(diǎn)故障不可達(dá)主要就是通過三個(gè)定時(shí)監(jiān)控任務(wù)來完成的:
? 每隔 10 秒每個(gè)哨兵節(jié)點(diǎn)會(huì)向主節(jié)點(diǎn)和從節(jié)點(diǎn)發(fā)送"info replication" 命令來獲取最新的拓?fù)浣Y(jié)構(gòu)
? 每隔 2 秒每個(gè)哨兵節(jié)點(diǎn)會(huì)向 Redis 節(jié)點(diǎn)的_sentinel_:hello 頻道發(fā)送自己對(duì)主節(jié)點(diǎn)是否故障的判斷以及自身的節(jié)點(diǎn)信息,并且其他的哨兵節(jié)點(diǎn)也會(huì)訂閱這個(gè)頻道來了解其他哨兵節(jié)點(diǎn)的信息以及對(duì)主節(jié)點(diǎn)的判斷
? 每隔 1 秒每個(gè)哨兵會(huì)向主節(jié)點(diǎn)、從節(jié)點(diǎn)、其他的哨兵節(jié)點(diǎn)發(fā)送一個(gè) “ping” 命令來做心跳檢測(cè)
如果在定時(shí) Job3 檢測(cè)不到節(jié)點(diǎn)的心跳,會(huì)判斷為“主觀下線”。如果該節(jié)點(diǎn)還是主節(jié)點(diǎn)那么還會(huì)通知到其他的哨兵對(duì)該主節(jié)點(diǎn)進(jìn)行心跳檢測(cè),這時(shí)主觀下線的票數(shù)超過了數(shù)時(shí),那么這個(gè)主節(jié)點(diǎn)確實(shí)就可能是故障不可達(dá)了,這時(shí)就由原來的主觀下線變?yōu)榱恕翱陀^下
線”。
故障轉(zhuǎn)移和 Leader 選舉
如果主節(jié)點(diǎn)被判定為客觀下線之后,就要選取一個(gè)哨兵節(jié)點(diǎn)來完成后面的故障轉(zhuǎn)移工作,選舉出一個(gè) leader,這里面采用的選舉算法為 Raft。選舉出來的哨兵 leader 就要來完成故障轉(zhuǎn)移工作,也就是在從節(jié)點(diǎn)中選出一個(gè)節(jié)點(diǎn)來當(dāng)新的主節(jié)點(diǎn),這部分的具體流程可參考引用. 《深入理解 Redis 哨兵搭建及原理》。
2、Redis-Cluster
https://redis.io/topics/cluster-tutorial/
Redis 的官方多機(jī)部署方案,Redis Cluster。一組 Redis Cluster 是由多個(gè) Redis 實(shí)例組成,官方推薦我們使用 6 實(shí)例,其中 3 個(gè)為主節(jié)點(diǎn),3 個(gè)為從結(jié)點(diǎn)。一旦有主節(jié)點(diǎn)發(fā)生故障的時(shí)候,Redis Cluster 可以選舉出對(duì)應(yīng)的從結(jié)點(diǎn)成為新的主節(jié)點(diǎn),繼續(xù)對(duì)外服務(wù),從而保證服務(wù)的高可用性。那么對(duì)于客戶端來說,知道知道對(duì)應(yīng)的 key 是要路由到哪一個(gè)節(jié)點(diǎn)呢?Redis Cluster把所有的數(shù)據(jù)劃分為 16384 個(gè)不同的槽位,可以根據(jù)機(jī)器的性能把不同的槽位分配給不同的 Redis 實(shí)例,對(duì)于 Redis 實(shí)例來說,他們只會(huì)存儲(chǔ)部分的 Redis 數(shù)據(jù),當(dāng)然,槽的數(shù)據(jù)是可以遷移的,不同的實(shí)例之間,可以通過一定的協(xié)議,進(jìn)行數(shù)據(jù)遷移。
1、槽
Redis 集群的功能限制;Redis 集群相對(duì) 單機(jī) 在功能上存在一些限制,需要 開發(fā)人員 提前了解,在使用時(shí)做好規(guī)避。JAVA CRC16 校驗(yàn)算法
? key 批量操作 支持有限。
? 類似 mset、mget 操作,目前只支持對(duì)具有相同 slot 值的 key 執(zhí)行 批量操作。對(duì)于 映射為不同 slot 值的 key 由于執(zhí)行 mget、mget 等操作可能存在于多個(gè)節(jié)點(diǎn)上,因此不被支持。
? key 事務(wù)操作 支持有限。
? 只支持 多 key 在 同一節(jié)點(diǎn)上 的 事務(wù)操作,當(dāng)多個(gè) key 分布在 不同 的節(jié)點(diǎn)上時(shí) 無法 使用事務(wù)功能。
? key 作為 數(shù)據(jù)分區(qū) 的最小粒度
? 不能將一個(gè) 大的鍵值 對(duì)象如 hash、list 等映射到 不同的節(jié)點(diǎn)。
? 不支持 多數(shù)據(jù)庫空間
? 單機(jī) 下的 Redis 可以支持 16 個(gè)數(shù)據(jù)庫(db0 ~ db15),集群模式 下只能使用 一個(gè) 數(shù)據(jù)庫空間,即 db0。
? 復(fù)制結(jié)構(gòu) 只支持一層
? 從節(jié)點(diǎn) 只能復(fù)制 主節(jié)點(diǎn),不支持 嵌套樹狀復(fù)制 結(jié)構(gòu)。
? 命令大多會(huì)重定向,耗時(shí)多
2、一致性 hash 一致性哈希 可以很好的解決 穩(wěn)定性問題,可以將所有的 存儲(chǔ)節(jié)點(diǎn) 排列在 收尾相接 的Hash 環(huán)上,每個(gè) key 在計(jì)算 Hash 后會(huì) 順時(shí)針 找到 臨接 的 存儲(chǔ)節(jié)點(diǎn) 存放。而當(dāng)有節(jié)點(diǎn) 加入 或 退出 時(shí),僅影響該節(jié)點(diǎn)在 Hash 環(huán)上 順時(shí)針相鄰 的 后續(xù)節(jié)點(diǎn)。
Hash 傾斜
如果節(jié)點(diǎn)很少,容易出現(xiàn)傾斜,負(fù)載不均衡問題。一致性哈希算法,引入了虛擬節(jié)點(diǎn),在整個(gè)環(huán)上,均衡增加若干個(gè)節(jié)點(diǎn)。比如 a1,a2,b1,b2,c1,c2,a1 和 a2 都是屬于 A 節(jié)點(diǎn)的。解決 hash 傾斜問題
3、部署 Cluster
1、創(chuàng)建 6 個(gè) redis 節(jié)點(diǎn)
3 主 3 從方式,從為了同步備份,主進(jìn)行 slot 數(shù)據(jù)分片
for port in $(seq 7001 7006); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port ${port}
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 192.168.56.10
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
appendonly yes
EOF
docker run -p ${port}:${port} -p 1${port}:1${port} --name redis-${port} \ -v /mydata/redis/node-${port}/data:/data \ -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \ -d redis:5.0.7 redis-server /etc/redis/redis.conf; \
done
docker stop $(docker ps -a |grep redis-700 | awk '{ print $1}')
docker rm $(docker ps -a |grep redis-700 | awk '{ print $1}')
2、使用 redis 建立集群
docker exec -it redis-7001 bash
redis-cli --cluster create 192.168.56.10:7001 192.168.56.10:7002 192.168.56.10:7003
192.168.56.10:7004 192.168.56.10:7005 192.168.56.10:7006 --cluster-replicas 1
3、測(cè)試集群效果
隨便進(jìn)入某個(gè) redis 容器
docker exec -it redis-7002 /bin/bash
使用 redis-cli 的 cluster 方式進(jìn)行連接
redis-cli -c -h 192.168.56.10 -p 7006
cluster info; 獲取集群信息
cluster nodes;獲取集群節(jié)點(diǎn)
Get/Set 命令測(cè)試,將會(huì)重定向
節(jié)點(diǎn)宕機(jī),slave 會(huì)自動(dòng)提升為 master,master 開啟后變?yōu)?slave
4、k8s 部署 redis
參照有狀態(tài)部署即可
七、Elasticsearch 集群
1、集群原理
https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html
https://www.elastic.co/guide/cn/elasticsearch/guide/current/distributed-cluster.html
elasticsearch 是天生支持集群的,他不需要依賴其他的服務(wù)發(fā)現(xiàn)和注冊(cè)的組件,如 zookeeper這些,因?yàn)樗麅?nèi)置了一個(gè)名字叫ZenDiscovery 的模塊,是 elasticsearch 自己實(shí)現(xiàn)的一套用于節(jié)點(diǎn)發(fā)現(xiàn)和選主等功能的組件,所以 elasticsearch 做起集群來非常簡(jiǎn)單,不需要太多額外的配置和安裝額外的第三方組件。
1、單節(jié)點(diǎn)
? 一個(gè)運(yùn)行中的 Elasticsearch 實(shí)例稱為一個(gè)節(jié)點(diǎn),而集群是由一個(gè)或者多個(gè)擁有相同cluster.name 配置的節(jié)點(diǎn)組成, 它們共同承擔(dān)數(shù)據(jù)和負(fù)載的壓力。當(dāng)有節(jié)點(diǎn)加入集群中或者從集群中移除節(jié)點(diǎn)時(shí),集群將會(huì)重新平均分布所有的數(shù)據(jù)。
? 當(dāng)一個(gè)節(jié)點(diǎn)被選舉成為 主節(jié)點(diǎn)時(shí), 它將負(fù)責(zé)管理集群范圍內(nèi)的所有變更,例如增加、刪除索引,或者增加、刪除節(jié)點(diǎn)等。 而主節(jié)點(diǎn)并不需要涉及到文檔級(jí)別的變更和搜索等操作,所以當(dāng)集群只擁有一個(gè)主節(jié)點(diǎn)的情況下,即使流量的增加它也不會(huì)成為瓶頸。任何節(jié)點(diǎn)都可以成為主節(jié)點(diǎn)。我們的示例集群就只有一個(gè)節(jié)點(diǎn),所以它同時(shí)也成為了主節(jié)點(diǎn)。
? 作為用戶,我們可以將請(qǐng)求發(fā)送到 集群中的任何節(jié)點(diǎn) ,包括主節(jié)點(diǎn)。 每個(gè)節(jié)點(diǎn)都知道任意文檔所處的位置,并且能夠?qū)⑽覀兊恼?qǐng)求直接轉(zhuǎn)發(fā)到存儲(chǔ)我們所需文檔的節(jié)點(diǎn)。無論我們將請(qǐng)求發(fā)送到哪個(gè)節(jié)點(diǎn),它都能負(fù)責(zé)從各個(gè)包含我們所需文檔的節(jié)點(diǎn)收集回?cái)?shù)據(jù),并將最終結(jié)果返回給客戶端。 Elasticsearch 對(duì)這一切的管理都是透明的。
2、集群健康
Elasticsearch 的集群監(jiān)控信息中包含了許多的統(tǒng)計(jì)數(shù)據(jù),其中最為重要的一項(xiàng)就是 集群健康 , 它在 status 字段中展示為 green 、 yellow 或者 red 。
GET /_cluster/health
status 字段指示著當(dāng)前集群在總體上是否工作正常。它的三種顏色含義如下:
green:所有的主分片和副本分片都正常運(yùn)行。
yellow:所有的主分片都正常運(yùn)行,但不是所有的副本分片都正常運(yùn)行。
red:有主分片沒能正常運(yùn)行。
3、分片
? 一個(gè) 分片 是一個(gè)底層的 工作單元 ,它僅保存了全部數(shù)據(jù)中的一部分。我們的文檔被存儲(chǔ)和索引到分片內(nèi),但是應(yīng)用程序是直接與索引而不是與分片進(jìn)行交互。分片就認(rèn)為是一個(gè)數(shù)據(jù)區(qū)
? 一個(gè)分片可以是 主 分片或者 副本 分片。索引內(nèi)任意一個(gè)文檔都?xì)w屬于一個(gè)主分片,所以主分片的數(shù)目決定著索引能夠保存的最大數(shù)據(jù)量。
? 在索引建立的時(shí)候就已經(jīng)確定了主分片數(shù),但是副本分片數(shù)可以隨時(shí)修改。
? 讓我們?cè)诎粋€(gè)空節(jié)點(diǎn)的集群內(nèi)創(chuàng)建名為 blogs 的索引。 索引在默認(rèn)情況下會(huì)被分配 5 個(gè)主分片, 但是為了演示目的,我們將分配 3 個(gè)主分片和一份副本(每個(gè)主分片擁有一個(gè)副本分片):
PUT /blogs{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}}
此時(shí)集群的健康狀況為 yellow 則表示全部 主分片都正常運(yùn)行(集群可以正常服務(wù)所有請(qǐng)求),但是 副本 分片沒有全部處在正常狀態(tài)。 實(shí)際上,所有 3 個(gè)副本分片都是 unassigned —— 它們都沒有被分配到任何節(jié)點(diǎn)。在同一個(gè)節(jié)點(diǎn)上既保存原始數(shù)據(jù)又保存副本是沒有意義的,因?yàn)橐坏┦チ四莻€(gè)節(jié)點(diǎn),我們也將丟失該節(jié)點(diǎn)上的所有副本數(shù)據(jù)。
當(dāng)前我們的集群是正常運(yùn)行的,但是在硬件故障時(shí)有丟失數(shù)據(jù)的風(fēng)險(xiǎn)。
4、新增節(jié)點(diǎn)
當(dāng)你在同一臺(tái)機(jī)器上啟動(dòng)了第二個(gè)節(jié)點(diǎn)時(shí),只要它和第一個(gè)節(jié)點(diǎn)有同樣的 cluster.name 配置,它就會(huì)自動(dòng)發(fā)現(xiàn)集群并加入到其中。 但是在不同機(jī)器上啟動(dòng)節(jié)點(diǎn)的時(shí)候,為了加入到同一集群,你需要配置一個(gè)可連接到的單播主機(jī)列表。 詳細(xì)信息請(qǐng)查看最好使用單播代替組播
此時(shí),cluster-health 現(xiàn)在展示的狀態(tài)為 green ,這表示所有 6 個(gè)分片(包括 3 個(gè)主分片和3 個(gè)副本分片)都在正常運(yùn)行。我們的集群現(xiàn)在不僅僅是正常運(yùn)行的,并且還處于 始終可用 的狀態(tài)。
5、水平擴(kuò)容-啟動(dòng)第三個(gè)節(jié)點(diǎn)
Node 1 和 Node 2 上各有一個(gè)分片被遷移到了新的 Node 3 節(jié)點(diǎn),現(xiàn)在每個(gè)節(jié)點(diǎn)上都擁有 2 個(gè)分片,而不是之前的 3 個(gè)。 這表示每個(gè)節(jié)點(diǎn)的硬件資源(CPU, RAM, I/O)將被更少的分片所共享,每個(gè)分片的性能將會(huì)得到提升。
在運(yùn)行中的集群上是可以動(dòng)態(tài)調(diào)整副本分片數(shù)目的,我們可以按需伸縮集群。讓我們把副本數(shù)從默認(rèn)的 1 增加到 2
PUT /blogs/_settings
{
"number_of_replicas" : 2
}
blogs 索引現(xiàn)在擁有 9 個(gè)分片:3 個(gè)主分片和 6 個(gè)副本分片。 這意味著我們可以將集群擴(kuò)容到 9 個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)上一個(gè)分片。相比原來 3 個(gè)節(jié)點(diǎn)時(shí),集群搜索性能可以提升 3 倍。
6、應(yīng)對(duì)故障
? 我們關(guān)閉的節(jié)點(diǎn)是一個(gè)主節(jié)點(diǎn)。而集群必須擁有一個(gè)主節(jié)點(diǎn)來保證正常工作,所以發(fā)生的第一件事情就是選舉一個(gè)新的主節(jié)點(diǎn): Node 2 。
? 在我們關(guān)閉 Node 1 的同時(shí)也失去了主分片 1 和 2 ,并且在缺失主分片的時(shí)候索引也不能正常工作。 如果此時(shí)來檢查集群的狀況,我們看到的狀態(tài)將會(huì)為 red :不是所有主分片都在正常工作。
? 幸運(yùn)的是,在其它節(jié)點(diǎn)上存在著這兩個(gè)主分片的完整副本, 所以新的主節(jié)點(diǎn)立即將這些分片在 Node 2 和 Node 3 上對(duì)應(yīng)的副本分片提升為主分片, 此時(shí)集群的狀態(tài)將會(huì)為 yellow 。 這個(gè)提升主分片的過程是瞬間發(fā)生的,如同按下一個(gè)開關(guān)一般。
? 為什么我們集群狀態(tài)是 yellow 而不是 green 呢? 雖然我們擁有所有的三個(gè)主分片,但是同時(shí)設(shè)置了每個(gè)主分片需要對(duì)應(yīng) 2 份副本分片,而此時(shí)只存在一份副本分片。 所以集群不能為 green 的狀態(tài),不過我們不必過于擔(dān)心:如果我們同樣關(guān)閉了 Node 2 ,我們的程序 依然 可以保持在不丟任何數(shù)據(jù)的情況下運(yùn)行,因?yàn)?Node 3 為每一個(gè)分片都保留著一份副本。
? 如果我們重新啟動(dòng) Node 1 ,集群可以將缺失的副本分片再次進(jìn)行分配。如果 Node 1依然擁有著之前的分片,它將嘗試去重用它們,同時(shí)僅從主分片復(fù)制發(fā)生了修改的數(shù)據(jù)文件。
7、問題與解決
1、主節(jié)點(diǎn)
主節(jié)點(diǎn)負(fù)責(zé)創(chuàng)建索引、刪除索引、分配分片、追蹤集群中的節(jié)點(diǎn)狀態(tài)等工作。Elasticsearch中的主節(jié)點(diǎn)的工作量相對(duì)較輕,用戶的請(qǐng)求可以發(fā)往集群中任何一個(gè)節(jié)點(diǎn),由該節(jié)點(diǎn)負(fù)責(zé)分發(fā)和返回結(jié)果,而不需要經(jīng)過主節(jié)點(diǎn)轉(zhuǎn)發(fā)。而主節(jié)點(diǎn)是由候選主節(jié)點(diǎn)通過 ZenDiscovery 機(jī)
制選舉出來的,所以要想成為主節(jié)點(diǎn),首先要先成為候選主節(jié)點(diǎn)。
2、候選主節(jié)點(diǎn)
在 elasticsearch 集群初始化或者主節(jié)點(diǎn)宕機(jī)的情況下,由候選主節(jié)點(diǎn)中選舉其中一個(gè)作為主節(jié)點(diǎn)。指定候選主節(jié)點(diǎn)的配置為:node.master: true。
當(dāng)主節(jié)點(diǎn)負(fù)載壓力過大,或者集中環(huán)境中的網(wǎng)絡(luò)問題,導(dǎo)致其他節(jié)點(diǎn)與主節(jié)點(diǎn)通訊的時(shí)候,主節(jié)點(diǎn)沒來的及響應(yīng),這樣的話,某些節(jié)點(diǎn)就認(rèn)為主節(jié)點(diǎn)宕機(jī),重新選擇新的主節(jié)點(diǎn),這樣的話整個(gè)集群的工作就有問題了,比如我們集群中有 10 個(gè)節(jié)點(diǎn),其中 7 個(gè)候選主節(jié)點(diǎn),1個(gè)候選主節(jié)點(diǎn)成為了主節(jié)點(diǎn),這種情況是正常的情況。但是如果現(xiàn)在出現(xiàn)了我們上面所說的主節(jié)點(diǎn)響應(yīng)不及時(shí),導(dǎo)致其他某些節(jié)點(diǎn)認(rèn)為主節(jié)點(diǎn)宕機(jī)而重選主節(jié)點(diǎn),那就有問題了,這剩下的 6 個(gè)候選主節(jié)點(diǎn)可能有 3 個(gè)候選主節(jié)點(diǎn)去重選主節(jié)點(diǎn),最后集群中就出現(xiàn)了兩個(gè)主節(jié)點(diǎn)的情況,這種情況官方成為“腦裂現(xiàn)象”;
集群中不同的節(jié)點(diǎn)對(duì)于 master 的選擇出現(xiàn)了分歧,出現(xiàn)了多個(gè)master 競(jìng)爭(zhēng),導(dǎo)致主分片和副本的識(shí)別也發(fā)生了分歧,對(duì)一些分歧中的分片標(biāo)識(shí)為了壞片。
3、數(shù)據(jù)節(jié)點(diǎn)
數(shù)據(jù)節(jié)點(diǎn)負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和相關(guān)具體操作,比如 CRUD、搜索、聚合。所以,數(shù)據(jù)節(jié)點(diǎn)對(duì)機(jī)器配置要求比較高,首先需要有足夠的磁盤空間來存儲(chǔ)數(shù)據(jù),其次數(shù)據(jù)操作對(duì)系統(tǒng) CPU、Memory 和 IO 的性能消耗都很大。通常隨著集群的擴(kuò)大,需要增加更多的數(shù)據(jù)節(jié)點(diǎn)來提高可用性。指定數(shù)據(jù)節(jié)點(diǎn)的配置:node.data: true。
elasticsearch 是允許一個(gè)節(jié)點(diǎn)既做候選主節(jié)點(diǎn)也做數(shù)據(jù)節(jié)點(diǎn)的,但是數(shù)據(jù)節(jié)點(diǎn)的負(fù)載較重,所以需要考慮將二者分離開,設(shè)置專用的候選主節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn),避免因數(shù)據(jù)節(jié)點(diǎn)負(fù)載重導(dǎo)致主節(jié)點(diǎn)不響應(yīng)。
4、客戶端節(jié)點(diǎn)
客戶端節(jié)點(diǎn)就是既不做候選主節(jié)點(diǎn)也不做數(shù)據(jù)節(jié)點(diǎn)的節(jié)點(diǎn),只負(fù)責(zé)請(qǐng)求的分發(fā)、匯總等等,但是這樣的工作,其實(shí)任何一個(gè)節(jié)點(diǎn)都可以完成,因?yàn)樵?elasticsearch 中一個(gè)集群內(nèi)的節(jié)點(diǎn)都可以執(zhí)行任何請(qǐng)求,其會(huì)負(fù)責(zé)將請(qǐng)求轉(zhuǎn)發(fā)給對(duì)應(yīng)的節(jié)點(diǎn)進(jìn)行處理。所以單獨(dú)增加這樣的節(jié)
點(diǎn)更多是為了負(fù)載均衡。指定該節(jié)點(diǎn)的配置為:
node.master: false
node.data: false
5、腦裂”問題可能的成因
1.網(wǎng)絡(luò)問題:集群間的網(wǎng)絡(luò)延遲導(dǎo)致一些節(jié)點(diǎn)訪問不到 master,認(rèn)為 master 掛掉了從而選舉出新的 master,并對(duì) master 上的分片和副本標(biāo)紅,分配新的主分片
2.節(jié)點(diǎn)負(fù)載:主節(jié)點(diǎn)的角色既為 master 又為 data,訪問量較大時(shí)可能會(huì)導(dǎo)致 ES 停止響應(yīng)造成大面積延遲,此時(shí)其他節(jié)點(diǎn)得不到主節(jié)點(diǎn)的響應(yīng)認(rèn)為主節(jié)點(diǎn)掛掉了,會(huì)重新選取主節(jié)點(diǎn)。
3.內(nèi)存回收:data 節(jié)點(diǎn)上的 ES 進(jìn)程占用的內(nèi)存較大,引發(fā) JVM 的大規(guī)模內(nèi)存回收,造成 ES進(jìn)程失去響應(yīng)。
? 腦裂問題解決方案:
? 角色分離:即 master 節(jié)點(diǎn)與 data 節(jié)點(diǎn)分離,限制角色;數(shù)據(jù)節(jié)點(diǎn)是需要承擔(dān)存儲(chǔ)和搜索的工作的,壓力會(huì)很大。所以如果該節(jié)點(diǎn)同時(shí)作為候選主節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn),
那么一旦選上它作為主節(jié)點(diǎn)了,這時(shí)主節(jié)點(diǎn)的工作壓力將會(huì)非常大,出現(xiàn)腦裂現(xiàn)象的概率就增加了。
? 減少誤判:配置主節(jié)點(diǎn)的響應(yīng)時(shí)間,在默認(rèn)情況下,主節(jié)點(diǎn) 3 秒沒有響應(yīng),其他節(jié)
點(diǎn)就認(rèn)為主節(jié)點(diǎn)宕機(jī)了,那我們可以把該時(shí)間設(shè)置的長(zhǎng)一點(diǎn),該配置是:
discovery.zen.ping_timeout: 5
? 選舉觸發(fā):discovery.zen.minimum_master_nodes:1(默認(rèn)是 1),該屬性定義的是為了形成一個(gè)集群,有主節(jié)點(diǎn)資格并互相連接的節(jié)點(diǎn)的最小數(shù)目。
? 一 個(gè) 有 10 節(jié) 點(diǎn) 的 集 群 , 且 每 個(gè) 節(jié) 點(diǎn) 都 有 成 為 主 節(jié) 點(diǎn) 的 資 格 ,discovery.zen.minimum_master_nodes 參數(shù)設(shè)置為 6。
? 正常情況下,10 個(gè)節(jié)點(diǎn),互相連接,大于 6,就可以形成一個(gè)集群。
? 若某個(gè)時(shí)刻,其中有 3 個(gè)節(jié)點(diǎn)斷開連接。剩下 7 個(gè)節(jié)點(diǎn),大于 6,繼續(xù)運(yùn)行之前的集群。而斷開的 3 個(gè)節(jié)點(diǎn),小于 6,不能形成一個(gè)集群。
? 該參數(shù)就是為了防止”腦裂”的產(chǎn)生。
? 建議設(shè)置為(候選主節(jié)點(diǎn)數(shù) / 2) + 1,
8、集群結(jié)構(gòu)
1、集群結(jié)構(gòu)
以三臺(tái)物理機(jī)為例。在這三臺(tái)物理機(jī)上,搭建了 6 個(gè) ES 的節(jié)點(diǎn),三個(gè) data 節(jié)點(diǎn),三個(gè) master節(jié)點(diǎn)(每臺(tái)物理機(jī)分別起了一個(gè) data 和一個(gè) master),3 個(gè) master 節(jié)點(diǎn),目的是達(dá)到(n/2)+1 等于 2 的要求,這樣掛掉一臺(tái) master 后(不考慮 data),n 等于 2,滿足參數(shù),其他兩個(gè) master 節(jié)點(diǎn)都認(rèn)為 master 掛掉之后開始重新選舉,
master 節(jié)點(diǎn)上
node.master = true
node.data = false
discovery.zen.minimum_master_nodes = 2
data 節(jié)點(diǎn)上
node.master = false
node.data = true
2、集群搭建
所有之前先運(yùn)行:sysctl -w vm.max_map_count=262144
我們只是測(cè)試,所以臨時(shí)修改。永久修改使用下面
#防止 JVM 報(bào)錯(cuò)
echo vm.max_map_count=262144 >> /etc/sysctl.conf
sysctl -p
0、準(zhǔn)備 docker 網(wǎng)絡(luò)
Docker 創(chuàng)建容器時(shí)默認(rèn)采用 bridge 網(wǎng)絡(luò),自行分配 ip,不允許自己指定。
在實(shí)際部署中,我們需要指定容器 ip,不允許其自行分配 ip,尤其是搭建集群時(shí),固定 ip是必須的。
我們可以創(chuàng)建自己的 bridge 網(wǎng)絡(luò) : mynet,創(chuàng)建容器的時(shí)候指定網(wǎng)絡(luò)為 mynet 并指定 ip即可。
查看網(wǎng)絡(luò)模式 docker network ls
;
創(chuàng)建一個(gè)新的 bridge 網(wǎng)絡(luò)
docker network create --driver bridge --subnet=172.18.12.0/16 --gateway=172.18.1.1
mynet
查看網(wǎng)絡(luò)信息
docker network inspect mynet
以后使用–network=mynet --ip 172.18.12.x 指定 ip
1、3-Master 節(jié)點(diǎn)創(chuàng)建
for port in $(seq 1 3); \
do \
mkdir -p /mydata/elasticsearch/master-${port}/config
mkdir -p /mydata/elasticsearch/master-${port}/data
chmod -R 777 /mydata/elasticsearch/master-${port}
cat << EOF >/mydata/elasticsearch/master-${port}/config/elasticsearch.yml
cluster.name: my-es #集群的名稱,同一個(gè)集群該值必須設(shè)置成相同的
node.name: es-master-${port} #該節(jié)點(diǎn)的名字
node.master: true #該節(jié)點(diǎn)有機(jī)會(huì)成為 master 節(jié)點(diǎn)
node.data: false #該節(jié)點(diǎn)可以存儲(chǔ)數(shù)據(jù)
network.host: 0.0.0.0
http.host: 0.0.0.0 #所有 http 均可訪問
http.port: 920${port}
transport.tcp.port: 930${port}
#discovery.zen.minimum_master_nodes: 2 #設(shè)置這個(gè)參數(shù)來保證集群中的節(jié)點(diǎn)可以知道其
它 N 個(gè)有 master 資格的節(jié)點(diǎn)。官方推薦(N/2)+1
discovery.zen.ping_timeout: 10s #設(shè)置集群中自動(dòng)發(fā)現(xiàn)其他節(jié)點(diǎn)時(shí) ping 連接的超時(shí)時(shí)間
discovery.seed_hosts: ["172.18.12.21:9301", "172.18.12.22:9302", "172.18.12.23:9303"] #設(shè)置集
群中的 Master 節(jié)點(diǎn)的初始列表,可以通過這些節(jié)點(diǎn)來自動(dòng)發(fā)現(xiàn)其他新加入集群的節(jié)點(diǎn),es7
的新增配置
cluster.initial_master_nodes: ["172.18.12.21"] #新集群初始時(shí)的候選主節(jié)點(diǎn),es7 的新增配置
EOF
docker run --name elasticsearch-node-${port} \ -p 920${port}:920${port} -p 930${port}:930${port} \ --network=mynet --ip 172.18.12.2${port} \
-e ES_JAVA_OPTS="-Xms300m -Xmx300m" \ -v
/mydata/elasticsearch/master-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/el
asticsearch.yml \ -v /mydata/elasticsearch/master-${port}/data:/usr/share/elasticsearch/data \ -v /mydata/elasticsearch/master-${port}/plugins:/usr/share/elasticsearch/plugins \ -d elasticsearch:7.4.2
done
docker stop $(docker ps -a |grep elasticsearch-node-* | awk '{ print $1}')
docker rm $(docker ps -a |grep elasticsearch-node-* | awk '{ print $1}')
2、3-Data-Node 創(chuàng)建
for port in $(seq 4 6); \
do \
mkdir -p /mydata/elasticsearch/node-${port}/config
mkdir -p /mydata/elasticsearch/node-${port}/data
chmod -R 777 /mydata/elasticsearch/node-${port}
cat << EOF >/mydata/elasticsearch/node-${port}/config/elasticsearch.yml
cluster.name: my-es #集群的名稱,同一個(gè)集群該值必須設(shè)置成相同的
node.name: es-node-${port} #該節(jié)點(diǎn)的名字
node.master: false #該節(jié)點(diǎn)有機(jī)會(huì)成為 master 節(jié)點(diǎn)
node.data: true #該節(jié)點(diǎn)可以存儲(chǔ)數(shù)據(jù)
network.host: 0.0.0.0
#network.publish_host: 192.168.56.10 #互相通信 ip,要設(shè)置為本機(jī)可被外界訪問的 ip,否則
無法通信
http.host: 0.0.0.0 #所有 http 均可訪問
http.port: 920${port}
transport.tcp.port: 930${port}
#discovery.zen.minimum_master_nodes: 2 #設(shè)置這個(gè)參數(shù)來保證集群中的節(jié)點(diǎn)可以知道其
它 N 個(gè)有 master 資格的節(jié)點(diǎn)。官方推薦(N/2)+1
discovery.zen.ping_timeout: 10s #設(shè)置集群中自動(dòng)發(fā)現(xiàn)其他節(jié)點(diǎn)時(shí) ping 連接的超時(shí)時(shí)間
discovery.seed_hosts: ["172.18.12.21:9301", "172.18.12.22:9302", "172.18.12.23:9303"] #設(shè)置集
群中的 Master 節(jié)點(diǎn)的初始列表,可以通過這些節(jié)點(diǎn)來自動(dòng)發(fā)現(xiàn)其他新加入集群的節(jié)點(diǎn),es7
的新增配置
cluster.initial_master_nodes: ["172.18.12.21"] #新集群初始時(shí)的候選主節(jié)點(diǎn),es7 的新增配置
EOF
docker run --name elasticsearch-node-${port} \ -p 920${port}:920${port} -p 930${port}:930${port} \ --network=mynet --ip 172.18.12.2${port} \ -e ES_JAVA_OPTS="-Xms300m -Xmx300m" \ -v
/mydata/elasticsearch/node-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/ela
sticsearch.yml \ -v /mydata/elasticsearch/node-${port}/data:/usr/share/elasticsearch/data \ -v /mydata/elasticsearch/node-${port}/plugins:/usr/share/elasticsearch/plugins \ -d elasticsearch:7.4.2
done
3、測(cè)試集群
http://192.168.56.10:9201/_nodes/process?pretty 查看節(jié)點(diǎn)狀況
http://192.168.56.10:9201/_cluster/stats?pretty 查看集群狀態(tài)
http://192.168.56.10:9201/_cluster/health?pretty 查看集群健康狀況
http://192.168.56.10:9202/_cat/nodes 查看各個(gè)節(jié)點(diǎn)信息
$ curl localhost:9200/_cat
/_cat/allocation
/_cat/shards
/_cat/shards/{index}
/_cat/master
/_cat/nodes
/_cat/indices
/_cat/indices/{index}
/_cat/segments
/_cat/segments/{index}
/_cat/count
/_cat/count/{index}
/_cat/recovery
/_cat/recovery/{index}
/_cat/health
/_cat/pending_tasks
/_cat/aliases
/_cat/aliases/{alias}
/_cat/thread_pool
/_cat/plugins
/_cat/fielddata
/_cat/fielddata/{fields}
/_cat/nodeattrs
/_cat/repositories
/_cat/snapshots/{repository}
3、k8s 上部署
有狀態(tài)服務(wù)
jvm.options -Xms100m
-Xmx512m
八、RabbitMQ 集群
1、集群形式
RabbiMQ 是用 Erlang 開發(fā)的,集群非常方便,因?yàn)?Erlang 天生就是一門分布式語言,但其本身并不支持負(fù)載均衡。
RabbitMQ 集群中節(jié)點(diǎn)包括內(nèi)存節(jié)點(diǎn)(RAM)、磁盤節(jié)點(diǎn)(Disk,消息持久化),集群中至少有一個(gè) Disk 節(jié)點(diǎn)。
? 普通模式(默認(rèn))
對(duì)于普通模式,集群中各節(jié)點(diǎn)有相同的隊(duì)列結(jié)構(gòu),但消息只會(huì)存在于集群中的一個(gè)節(jié)點(diǎn)。對(duì)于消費(fèi)者來說,若消息進(jìn)入 A 節(jié)點(diǎn)的 Queue 中,當(dāng)從 B 節(jié)點(diǎn)拉取時(shí),RabbitMQ 會(huì)將消息從 A 中取出,并經(jīng)過 B 發(fā)送給消費(fèi)者。
應(yīng)用場(chǎng)景:該模式各適合于消息無需持久化的場(chǎng)合,如日志隊(duì)列。當(dāng)隊(duì)列非持久化,且創(chuàng)建該隊(duì)列的節(jié)點(diǎn)宕機(jī),客戶端才可以重連集群其他節(jié)點(diǎn),并重新創(chuàng)建隊(duì)列。若為持久化,只能等故障節(jié)點(diǎn)恢復(fù)。
? 鏡像模式
與普通模式不同之處是消息實(shí)體會(huì)主動(dòng)在鏡像節(jié)點(diǎn)間同步,而不是在取數(shù)據(jù)時(shí)臨時(shí)拉取,高可用;該模式下,mirror queue 有一套選舉算法,即 1 個(gè) master、n 個(gè) slaver,生產(chǎn)者、消費(fèi)者的請(qǐng)求都會(huì)轉(zhuǎn)至 master。
應(yīng)用場(chǎng)景:可靠性要求較高場(chǎng)合,如下單、庫存隊(duì)列。
缺點(diǎn):若鏡像隊(duì)列過多,且消息體量大,集群內(nèi)部網(wǎng)絡(luò)帶寬將會(huì)被此種同步通訊所消耗。
(1)鏡像集群也是基于普通集群,即只有先搭建普通集群,然后才能設(shè)置鏡像隊(duì)列。
(2)若消費(fèi)過程中,master 掛掉,則選舉新 master,若未來得及確認(rèn),則可能會(huì)重復(fù)消費(fèi)
1、搭建集群
mkdir /mydata/rabbitmq
cd rabbitmq/
mkdir rabbitmq01 rabbitmq02 rabbitmq03
docker run -d --hostname rabbitmq01 --name rabbitmq01 -v
/mydata/rabbitmq/rabbitmq01:/var/lib/rabbitmq -p 15673:15672 -p 5673:5672 -e
RABBITMQ_ERLANG_COOKIE='wxn' rabbitmq:management
docker run -d --hostname rabbitmq02 --name rabbitmq02 -v
/mydata/rabbitmq/rabbitmq02:/var/lib/rabbitmq -p 15674:15672 -p 5674:5672 -e
RABBITMQ_ERLANG_COOKIE='wxn' --link rabbitmq01:rabbitmq01
rabbitmq:management
docker run -d --hostname rabbitmq03 --name rabbitmq03 -v
/mydata/rabbitmq/rabbitmq03:/var/lib/rabbitmq -p 15675:15672 -p 5675:5672 -e
RABBITMQ_ERLANG_COOKIE='wxn' --link rabbitmq01:rabbitmq01 --link
rabbitmq02:rabbitmq02 rabbitmq:management
--hostname 設(shè)置容器的主機(jī)名
RABBITMQ_ERLANG_COOKIE 節(jié)點(diǎn)認(rèn)證作用,部署集成時(shí) 需要同步該值
2、節(jié)點(diǎn)加入集群
docker exec -it rabbitmq01 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
Exit
進(jìn)入第二個(gè)節(jié)點(diǎn)
docker exec -it rabbitmq02 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit
進(jìn)入第三個(gè)節(jié)點(diǎn)
docker exec -it rabbitmq03 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit
3、實(shí)現(xiàn)鏡像集群
docker exec -it rabbitmq01 bash
rabbitmqctl set_policy -p / ha "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}' 可以使用 rabbitmqctl list_policies -p /;查看 vhost/下面的所有 policy
在 cluster 中任意節(jié)點(diǎn)啟用策略,策略會(huì)自動(dòng)同步到集群節(jié)點(diǎn)
rabbitmqctl set_policy-p/ha-all"^"’{“ha-mode”:“all”}’
策略模式 all 即復(fù)制到所有節(jié)點(diǎn),包含新增節(jié)點(diǎn),策略正則表達(dá)式為 “^” 表示所有匹配所有隊(duì)列名稱。“^hello”表示只匹配名為 hello 開始的隊(duì)列
2、集群測(cè)試
隨便在 mq 上創(chuàng)建一個(gè)隊(duì)列,發(fā)送一個(gè)消息,保證整個(gè)集群其他節(jié)點(diǎn)都有這個(gè)消息。如果
master 宕機(jī),其他節(jié)點(diǎn)也能成為新的 master
3、k8s 上部署
九、Jenkins
1、Jenkins
官方文檔 https://jenkins.io/zh/doc/pipeline/tour/getting-started/
Jenkins 是開源 CI&CD 軟件領(lǐng)導(dǎo)者, 提供超過 1000 個(gè)插件來支持構(gòu)建、部署、自動(dòng)化, 滿足任何項(xiàng)目的需要。
2、Jenkins 流水線
https://jenkins.io/zh/doc/book/pipeline
3、k8s 部署 nacos
docker run --env MODE=standalone --name nacos \ -v /mydata/nacos/conf:/home/nacos/conf -d -p 8848:8848 nacos/nacos-server:1.1.4
4、k8s 部署 sentinel
可以制作一個(gè)鏡像并啟動(dòng)它,暴露訪問
docker run --name sentinel -d -p 8858:8858 -d bladex/sentinel-dashboard:1.6.3
5、k8s 部署 zipkin
docker run -d -p 9411:9411 openzipkin/zipkin
或者
docker run --env STORAGE_TYPE=elasticsearch --env ES_HOSTS=192.168.56.10:9200
openzipkin/zipkin
十、K8S部署應(yīng)用
1、k8s部署應(yīng)用流程
文章來源:http://www.zghlxwxcb.cn/news/detail-679319.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-679319.html
2、生產(chǎn)環(huán)境配置抽取
3、創(chuàng)建微服務(wù)Dockerfile
4、創(chuàng)建微服務(wù)k8s部署描述文件
5、理解targetPort、port、nodePort
6、流水線第一步拉取gitee代碼&參數(shù)化構(gòu)建&環(huán)境變量
7、流水線第二步Sonar代碼質(zhì)量分析
8、流水線第三步構(gòu)建&推送鏡像
9、流水線第四步編寫完成
10、部署-移植數(shù)據(jù)庫
11、流水線部署所有微服務(wù)
12、部署整合阿里云鏡像倉庫
13、Jenkins修改阿里云鏡像倉庫
14、流水線部署gateway
15、流水線部署auth-server
16、部署cart
17、部署coupon
18、修改為共有倉庫
19、部署前置nginx
20、創(chuàng)建網(wǎng)關(guān)與應(yīng)用路由
21、部署前端vue項(xiàng)目
22、滾動(dòng)更新部署admin-vue-app
23、線上預(yù)警和監(jiān)控
到了這里,關(guān)于商城-學(xué)習(xí)整理-集群-K8S-集群環(huán)境部署(二十四)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!