mysql主从复制、redis基础、持久化和主从复制
一、mysql(mariadb)基礎
1、基礎命令(centos7操作系統下)
1.啟動mysql systemctl start mariadb 2.linux客戶端連接自己 mysql -uroot -p -h 127.0.0.1-u 用戶-p 密碼驗證-h 連接的主機地址3.遠程鏈接mysql服務端 mysql -uroot -p -h 192.168.3.1154.修改mysql密碼 # 修改當前用戶的密碼 set password = PASSWORD('mariadb123');# 修改其他用戶的密碼 set password for 'username'@'host' = PASSWORD('newpassword') 5.創建mysql用戶 create user xiaoming@'%' identified by 'xm666';6.查詢mysql庫中的用戶信息 use mysql; # mysql是默認存在的庫,儲存著用戶的信息,密碼之類的 select host,user,password from user;7.授權語句 給小明這個用戶,授予創建數據庫的權限 mysql中使用grant命令對賬戶進行授權,grant命令常見格式如下grant 權限 on 數據庫.表名 to 賬戶@主機名 對特定數據庫中的特定表授權 grant 權限 on 數據庫.* to 賬戶@主機名 對特定數據庫中的所有表給與授權 grant 權限1,權限2,權限3 on *.* to 賬戶@主機名 對所有庫中的所有表給與多個授權 grant all privileges on *.* to 賬戶@主機名 對所有庫和所有表授權所有權限# 授予小明創建的權限,對于所有的庫表生效 grant create on *.* to xiaoming@"%";# 創建用戶并授予用戶只有創建test數據庫的權限 grant create on test.* to xiaoming2@"%" identified by 'xm2666';# 授予用戶最大的權限,所有的權限 grant all privileges on *.* to username@'%' identified by 'password';# 刷新權限 flush privileges; # 刷新使授權立即生效# 查看用戶權限 show grants for 'xiaoming'@'%';8.移除權限 revoke all privileges on *.* from xiaoming@"%";?
2、數據庫的備份與恢復
# 備份 mysqldump -u root -p --all-databases > /tmp/db.sql# 數據導入,方式有幾種 第一種 source /tmp/db.sql;第二種 mysql -uroot -p < /tmp/db.sql 第三種 使用navicat工具第四種,如果你數據量特別大的話 使用第三方工具 xtrabackup?
二、mysql主從復制
1、mysql主從復制背景
1.如果你是單點數據庫,數據庫掛了,你整個項目就掛了
2.如果你是主備數據庫,掛了一臺主庫,我可能還有千千萬萬個備用的數據庫
3.原理
MySQL數據庫的主從復制是其自帶的功能,主從復制并不是復制磁盤上的數據庫文件,而是通過主庫的binlog日志復制到需要同步的從服務器上。
在復制的過程中,一臺服務器充當主服務器(Master),接收來自用戶的內容更新,而一個或多個其他的服務器充當從服務器(slave),接收來自Master上binlog文件的日志內容,解析出SQL,重新更新到Slave,使得主從服務器數據達到一致。
主從復制的邏輯有以下幾種
一主一從,單向主從同步模式,只能在Master端寫入數據
?
一主多從
?
?
雙主主復制邏輯架構,此架構可以在Master1或Master2進行數據寫入,或者兩端同時寫入(特殊設置)
?
4.應用場景
利用復制功能當Master服務器出現問題時,我們可以人工的切換到從服務器繼續提供服務,此時服務器的數據和宕機時的數據幾乎完全一致。
復制功能也可用作數據備份,但是如果人為的執行drop,delete等語句刪除,那么從庫的備份功能也就失效了
?
2、mysql主從復制主庫的配置步驟
1.在matser(192.168.3.115)主庫上的操作,開啟主庫功能 # 先把主數據庫停了 systemctl stop mariadb # 編輯數據庫的配置文件 /etc/my.cnf ,寫入如下信息 [mysqld] server-id=6 # 這個server-id只要與你從庫的server-id不一樣即可 log-bin=master-logbin # 生成二進制日志,記錄數據的變化# 重啟數據庫 systemctl start mariadb2.在主庫創建用戶,用于同步數據 create user xiaoming@'%' identified by 'xm666';授予用戶,slave從庫的身份 grant replication slave on *.* to 'xiaoming'@'%';3.鎖定數據庫的庫表,禁止寫入 這個命令是全局讀鎖定,執行了命令之后所有庫所有表都被鎖定只讀。一般都是用在數據庫聯機備份,這個時候數據庫的寫操作將被阻塞,讀操作順利進行。 解鎖語句是:UNLOCK TABLES; flush table with read lock;記錄下主庫的狀態,記錄下,日志文件的名字,和位置 show master status; 4.導出主庫的數據 mysqldump -u root -p --all-databases > /tmp/db.sql5.遠程傳輸主庫的數據,給從庫,進行導入 scp /tmp/db.sql root@192.168.3.27:/tmp/6.解鎖主庫的鎖,寫入數據,查看從庫是否同步 unlock tables;?
3、從庫slave(192.168.3.27)機器的配置步驟
1.在從庫的 /etc/my.cnf中添加參數,添加只讀參數 [mysqld] server-id=3 read-only=true2.重啟數據庫 systemctl restart mariadb 在從庫中導入主庫的數據 mysql -uroot -p < /tmp/db.sql 3.一條語句,開啟主從之間的復制關系 用root用戶,進入mysql數據庫,輸入命令: change master to master_host='192.168.3.115', # 主數據庫的ip master_user='xiaoming', # 普通用戶的用戶名 master_password='xm666', # 普通用戶的密碼 master_log_file='master-logbin.000002', # 主庫show master status;日志文件的名字 master_log_pos=492; # 主庫show master status;記錄的位置4.開啟slave同步功能 start slave;5.檢查slave機器的主從是否正確 show slave status\G 查看主從同步是否正確確保如下兩條參數,是yes,即主從復制正確 Relay_Master_Log_File: master-logbin.000002Slave_IO_Running: YesSlave_SQL_Running: Yes6.此時mariadb數據庫,請退出root用戶,使用普通用戶配置,因為root身份權限太大,無法達到read-only效果 6.此時mariadb數據庫,請退出root用戶,使用普通用戶配置,因為root身份權限太大,無法達到read-only效果 6.此時mariadb數據庫,請退出root用戶,使用普通用戶配置,因為root身份權限太大,無法達到read-only效果7.登錄一個普通用戶mysql -u xiaoming -p 8.此時在主庫寫入數據,查看從庫是否正確同步9.從庫無法寫入數據,即為正常10.完成主從同步,讀寫分離實驗
?
三、redis基礎
redis是一種高級的key:value存儲系統,其中value支持五種數據類型
String: 字符串
Hash: 散列
List: 列表
Set: 集合
Sorted Set: 有序集合
?我的另一篇redis博客
1、strings類型
操作
set 設置key get 獲取key append 追加string mset 設置多個鍵值對 mget 獲取多個鍵值對 del 刪除key incr 遞增+1 decr 遞減-1?
示例
127.0.0.1:6379> set name 'dog' # 設置key OK 127.0.0.1:6379> get name # 獲取value "dog" 127.0.0.1:6379> set name 'BigDog' # 覆蓋key OK 127.0.0.1:6379> get name # 獲取value "BigDog" 127.0.0.1:6379> append name ' is you' # 向name這個key追加 (integer) 13 127.0.0.1:6379> get name # 獲取value "BigDog is you" 127.0.0.1:6379> mset age 18 hight 180 long 18.8 # 一次性設置多個鍵值對 OK 127.0.0.1:6379> mget age hight long # 一次性獲取多個鍵的值 1) "18" 2) "180" 3) "18.8" 127.0.0.1:6379> get age # 獲取value "18" 127.0.0.1:6379> keys * # 找到所有key 1) "long" 2) "hight" 3) "age" 4) "name" 127.0.0.1:6379> del name # 刪除key (integer) 1 127.0.0.1:6379> get name # 獲取不存在的value,為nil (nil) 127.0.0.1:6379> set num 10 OK 127.0.0.1:6379> get num "10" 127.0.0.1:6379> incr num # 遞增+1 (integer) 11 127.0.0.1:6379> get num "11" 127.0.0.1:6379> decr num # 遞減-1 (integer) 10 127.0.0.1:6379> get num "10"?
2、list類型
操作
lpush 從列表左邊插 rpush 從列表右邊插 lrange 獲取一定長度的元素 lrange key start stop(相當于獲取切片的內容) ltrim 截取一定長度列表 lpop 刪除最左邊一個元素 rpop 刪除最右邊一個元素 lpushx/rpushx key存在則添加值,不存在不處理?
示例
127.0.0.1:6379> lpush list1 'a' 'b' 'c' 'd' # 新建一個list1,從左邊放入四個元素 (integer) 4 127.0.0.1:6379> llen list1 # 查看list1的長度 (integer) 4 127.0.0.1:6379> lrange list1 0 -1 # 查看list所有元素 1) "d" 2) "c" 3) "b" 4) "a" 127.0.0.1:6379> rpush list1 'haha' # 從右邊插入haha (integer) 5 127.0.0.1:6379> lrange list1 0 -1 1) "d" 2) "c" 3) "b" 4) "a" 5) "haha" 127.0.0.1:6379> lpushx list3 'xixi' # list3存在則添加元素,不存在則不作處理 (integer) 0 127.0.0.1:6379> ltrim list1 0 3 # 截取隊列的值,從索引0取到3,刪除其余的元素 OK 127.0.0.1:6379> lrange list1 0 -1 1) "d" 2) "c" 3) "b" 4) "a" 127.0.0.1:6379> lpop list1 # 刪除左邊的第一個 "d" 127.0.0.1:6379> lrange list1 0 -1 1) "c" 2) "b" 3) "a" 127.0.0.1:6379> rpop list1 # 刪除右邊的第一個 "a" 127.0.0.1:6379> lrange list1 0 -1 1) "c" 2) "b"?
3、set集合類型
redis的集合,是一種無序的集合,集合中的元素沒有先后順序,且集合成員是唯一的。
操作
sadd/srem 添加/刪除 元素 sismember 判斷是否為set的一個元素 smembers 返回集合所有的成員 sdiff 返回一個集合和其他集合的差異 sinter 返回幾個集合的交集 sunion 返回幾個集合的并集?
示例
127.0.0.1:6379> sadd school class1 class2 # 添加一個名叫school的集合,有2個元素,不加引號就當做字符串處理 (integer) 2 127.0.0.1:6379> smembers school # 查看集合school成員 1) "class1" 2) "class2" 127.0.0.1:6379> srem school class1 # 刪除school的class1成員 (integer) 1 127.0.0.1:6379> smembers school 1) "class2" 127.0.0.1:6379> sismember school class1 # 是否是school的成員,不是返回0,是返回1 (integer) 0 127.0.0.1:6379> sadd school class3 # 給school添加一個新成員 (integer) 1 127.0.0.1:6379> smembers school 1) "class3" 2) "class2" 127.0.0.1:6379> sadd school2 class3 class4 # 添加一個名叫school2的集合,有2個元素 (integer) 1 127.0.0.1:6379> smembers school2 1) "class3" 2) "class4" 127.0.0.1:6379> sdiff school school2 # 找出集合school中有的,而school2中沒有的元素 1) "class2" 127.0.0.1:6379> sdiff school2 school # 找出集合school2中有的,而school中沒有的元素 1) "class4" 127.0.0.1:6379> sinter school school2 # 找出school和school2的交集 1) "class3" 127.0.0.1:6379> sunion school school2 # 找出school和school2的并集(自動去重) 1) "class3" 2) "class4" 3) "class2"?
4、哈希數據結構
hashes即哈希。哈希是從redis-2.0.0版本之后才有的數據結構。
hashes存的是字符串和字符串值之間的映射,比如一個用戶要存儲其全名、姓氏、年齡等等,就很適合使用哈希。
操作
hset 設置散列值 hget 獲取散列值 hmset 設置多對散列值 hmget 獲取多對散列值 hsetnx 如果散列已經存在,則不設置(防止覆蓋key) hkeys 返回所有keys hvals 返回所有values hlen 返回散列包含域(field)的數量 hdel 刪除散列指定的域(field) hexists 判斷是否存在?
注意
Hash不支持多次嵌套,即 "key": {'field': '不能再對應字典'}"key": {'field': {...}} --> 錯誤 若想嵌套字典,可以json.dumps后存入,取出數據的時候可以json.loads?
語法
hset key field value 結構如下key: {field1: value1,field2: value2,}?
示例
127.0.0.1:6379> hset school name 'ChinaSchool' # 創建一個key為school的哈希數據 (integer) 1 127.0.0.1:6379> hget school name # 獲取school的name的值 "ChinaSchool" 127.0.0.1:6379> hmset school age 100 area 2000 # 給school批量設置鍵值對 OK 127.0.0.1:6379> hmget school name age area # 批量獲取school的鍵對應的值 1) "ChinaSchool" 2) "100" 3) "2000" 127.0.0.1:6379> hkeys school # 獲取school的所有key 1) "name" 2) "age" 3) "area" 127.0.0.1:6379> hvals school # 獲取school的所有值 1) "ChinaSchool" 2) "100" 3) "2000" 127.0.0.1:6379> hlen school # 獲取school的長度 (integer) 3 127.0.0.1:6379> hexists school name # 判斷school中是否有name這個鍵,有就返回1,沒有就返回0 (integer) 1 127.0.0.1:6379> hdel shcool area # 刪除school中的area鍵值對 (integer) 1?
5、額外的危險操作(慎用)
獲取redis數據庫中所有的鍵(這個不危險) keys *刪除所有Key,可以使用Redis的flushdb和flushall命令(危險慎用) # 刪除當前數據庫中的所有Key flushdb# 刪除所有數據庫中的key flushall?
四、redis發布者訂閱者
發布者: PUBLISH channel msg將信息 message 發送到指定的頻道 channel頻道 channel 自定義頻道的名字訂閱者: SUBSCRIBE channel [channel ...]訂閱頻道,可以同時訂閱多個頻道UNSUBSCRIBE [channel ...]取消訂閱指定的頻道, 如果不指定頻道,則會取消訂閱所有頻道PSUBSCRIBE pattern [pattern ...]訂閱一個或多個符合給定模式的頻道(正則匹配),每個模式以 * 作為匹配符,比如 it* 匹配所有以 it 開頭的頻道( it.news 、 it.blog 、 it.tweets 等等), news.* 匹配所有以 news. 開頭的頻道( news.it 、 news.global.today 等等),諸如此類PUNSUBSCRIBE [pattern [pattern ...]]退訂指定的規則, 如果沒有參數則會退訂所有規則PUBSUB subcommand [argument [argument ...]]查看訂閱與發布系統狀態注意:使用發布訂閱模式實現的消息隊列,當有客戶端訂閱channel后只能收到后續發布到該頻道的消息,之前發送的不會緩存,必須Provider和Consumer同時在線?
五、redis數據持久化
redis的缺點:
redis數據放在內存中
重啟服務器丟失數據
重啟redis服務丟失數據
斷電丟失數據
為了防止redis數據丟失,進行持久化,將數據,寫入到一個文件中
?
1、redis持久化之RDB
redis提供了RDB持久化的功能,這個功能可以將redis在內存中的的狀態保存到硬盤中,它可以手動執行。
也可以再redis.conf中配置,定期執行。
RDB持久化產生的RDB文件是一個經過壓縮的二進制文件,這個文件被保存在硬盤中,redis可以通過這個文件還原數據庫當時的狀態。
RDB的原理是
基于內存的數據快照
定期執行數據快照
手動觸發數據快照
Redis會將數據集的快照dump到dump.rdb文件中
可以通過配置文件來修改Redis服務器dump快照的頻率
RDB優點:
速度快,適合做備份,主從復制就是基于RDB持久化功能實現
rdb通過在redis中使用save命令觸發 rdb
?
1. 配置rdb數據持久化
1.在配置文件中,添加rdb持久化參數 vim redis-6379.conf 寫入如下配置 port 6379 daemonize yes pidfile /data/6379/redis.pid loglevel notice logfile "/data/6379/redis.log" protected-mode yes dir /data/6379 # 定義持久化文件存儲位置(rdb和aof) dbfilename dbmp.rdb # rdb持久化文件 save 900 1 # rdb機制 每900秒 如果至少有1個key發生變化,則dump內存快照(相當于手動save觸發rdb持久化文件) save 300 10 # 在300秒(5分鐘)之后,如果至少有10個key發生變化,則dump內存快照。 save 60 10000 # 在60秒(1分鐘)之后,如果至少有10000個key發生變化,則dump內存快照。2.觸發rdb持久化,可以手動save命令,生成 dump.rdb持久化文件3.重啟redis,數據不再丟失4. 測試 進入redis客戶端 redis-cli127.0.0.1:6379> set age 18 OK 127.0.0.1:6379> save OK5.進入/data/6379查看是否生成了 dbmp.rdb 持久化文件 注意:rdb數據文件是二進制文件,人為的看不懂6.kill掉redis進程,再重啟,進入redis keys * 查看數據是否還在?
2、redis持久化之aof
AOF(append-only log file)
記錄服務器執行的所有變更操作命令(例如set del等),并在服務器啟動時,通過重新執行這些命令來還原數據集
AOF 文件中的命令全部以redis協議的格式保存,新命令追加到文件末尾。
優點:最大程序保證數據不丟
缺點:日志記錄非常大
?
1. 配置方式
?
1,在配置文件中,添加aof參數 參數解釋: appendonly yes # 開啟aof功能# appendfsync選擇一個策略寫入配置文件即可,這里使用每分鐘 appendfsync everysec # 每秒鐘同步一次,該策略為AOF的缺省策略。 appendfsync always # 每次有數據修改發生時都會寫入AOF文件。 appendfsync no # 從不同步。高效但是數據不會被持久化 配置如下: port 6379 daemonize yes pidfile /data/6379/redis.pid loglevel notice logfile "/data/6379/redis.log" protected-mode yes dir /data/6379 dbfilename dbmp.rdb save 900 1 save 300 10 save 60 10000appendonly yes appendfsync everysec2,重啟redis數據庫,加載aof功能 會在/data/6379目錄下生成 appendonly.aof 文件3,appendonly.aof 文件是人可以看懂的記錄了sql操作的文件4,測試 進入redis客戶端 redis-cli127.0.0.1:6379> set long 18 OK5,進入/data/6379查看appendonly.aof 文件的內容6,kill掉redis進程,再重啟,進入redis keys * 查看數據是否還在?
?
3、在不重啟redis的情況下,切換rdb數據到aof數據中
?
1.配置redis支持rdb持久化2.啟動redis客戶端,通過命令,臨時切換到aof模式 127.0.0.1:6379> CONFIG set appendonly yes # 開啟AOF功能 OK 127.0.0.1:6379> CONFIG SET save "" # 關閉RDB功能 OK3.檢查此時的數據持久化方式是rdb,還是aof,檢查appendonly.aof文件,數據變動 tail -f appendonly.aof4.此時aof還未永久生效,寫入參數到配置文件 編輯redis-6379.conf 添加如下參數 appendonly yes appendfsync everysec?
4、redis持久化方式有什么區別
rdb:基于快照的持久化,速度更快,一般用作備份,主從復制也是依賴于rdb持久化功能
aof:以追加的方式記錄redis操作日志的文件??梢宰畲蟪潭鹊谋WCredis數據安全,類似于mysql的binlog
?
六、redis主從同步實現
原理:
1. 從服務器向主服務器發送 SYNC 命令。
2. 接到 SYNC 命令的主服務器會調用BGSAVE 命令,創建一個 RDB 文件,并使用緩沖區記錄接下來執行的所有寫命令。
3. 當主服務器執行完 BGSAVE 命令時,它會向從服務器發送 RDB 文件,而從服務器則會接收并載入這個文件。
4. 主服務器將緩沖區儲存的所有寫命令發送給從服務器執行。
小知識:
1. 在開啟主從復制的時候,使用的是RDB方式的,同步主從數據的
2. 同步開始之后,通過主庫命令傳播的方式,主動的復制方式實現
3. 2.8以后實現PSYNC的機制,實現斷線重連
?
1、使用配置文件進行redis主從同步配置
準備三個redis數據庫,redis支持多實例
三個配置文件,僅僅是端口的不同
在三個配置文件中,添加主從同步的參數,
三個配置文件參數是一樣的,唯一不同的是,
在從庫中需要指定它的主庫是誰即可,
例如6380的配置
slaveof 127.0.0.1 6379 代表這個redis庫是6379的從庫
?
1. 三個配置文件參信息如下 # redis-6379.conf(主redis) port 6379 daemonize yes pidfile /data/6379/redis.pid loglevel notice logfile "/data/6379/redis.log" dir /data/6379 protected-mode yes dbfilename dbmp.rdb save 900 1 save 300 10 save 60 10000# redis-6380.conf(從redis) port 6380 daemonize yes pidfile /data/6380/redis.pid loglevel notice logfile "/data/6380/redis.log" dir /data/6380 protected-mode yes dbfilename dbmp.rdb save 900 1 save 300 10 save 60 10000 slaveof 127.0.0.1 6379# redis-6381.conf(從redis) port 6381 daemonize yes pidfile /data/6381/redis.pid loglevel notice logfile "/data/6381/redis.log" dir /data/6381 protected-mode yes dbfilename dbmp.rdb save 900 1 save 300 10 save 60 10000 slaveof 127.0.0.1 63792.啟動三個redis實例 redis-server redis-6379.conf redis-server redis-6380.conf redis-server redis-6381.conf3.查看主從同步身份 1,redis-cli -p 6379 info replication # Replication role:master connected_slaves:2 slave0:ip=127.0.0.1,port=6380,state=online,offset=28,lag=1 slave1:ip=127.0.0.1,port=6381,state=online,offset=28,lag=12,redis-cli -p 6380 info replication # Replication role:slave master_host:127.0.0.1 master_port:63793,redis-cli -p 6381 info replication # Replication role:slave master_host:127.0.0.1 master_port:63794.測試 # 在6379主庫 redis-cli -p 6379127.0.0.1:6379> set uzi good OK# 在6380從庫 redis-cli -p 6380127.0.0.1:6380> get uzi "good"# 在6381從庫 redis-cli -p 6381127.0.0.1:6381> get uzi "good"?
2、使用命令行進行redis主從同步配置
1. 6380/6381命令行 redis-cli -p 6380 127.0.0.1:6380> SLAVEOF 127.0.0.1 6379 #指明主庫的地址 redis-cli -p 6381 127.0.0.1:6381> SLAVEOF 127.0.0.1 6379 #指明主庫的地址2. 檢查主從狀態 主庫: 127.0.0.1:6379> info replication從庫: 127.0.0.1:6380> info replication 127.0.0.1:6381> info replication?
3、如果我主庫掛了怎么辦
解決方案:手動切換主從身份,選舉一個新的主庫 1.干掉6379主庫 redis-cli -p 6379 shutdown2.在6380上關閉自己的slave身份 127.0.0.1:6380> slaveof no one 3.在6381上給與新的主人身份 127.0.0.1:6381> salveof 127.0.0.1 6380 4.修改完畢,還得修改配置文件,永久生效?
轉載于:https://www.cnblogs.com/Zzbj/p/10274367.html
總結
以上是生活随笔為你收集整理的mysql主从复制、redis基础、持久化和主从复制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BZOJ2115 [Wc2011] Xo
- 下一篇: 在vue项目npm run build后