1、mysql(mariadb)基礎
一、基礎命令(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.115 4.修改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@"%";
二、數據庫的備份與恢復
# 備份 mysqldump -u root -p --all-databases > /tmp/db.sql # 數據導入,方式有幾種 第一種 source /tmp/db.sql; 第二種 mysql -uroot -p < /tmp/db.sql 第三種 使用navicat工具 第四種,若是你數據量特別大的話 使用第三方工具 xtrabackup
2、mysql主從複製
一、mysql主從複製背景
1.若是你是單點數據庫,數據庫掛了,你整個項目就掛了mysql
2.若是你是主備數據庫,掛了一臺主庫,我可能還有千千萬萬個備用的數據庫linux
3.原理
MySQL數據庫的主從複製是其自帶的功能,主從複製並非複製磁盤上的數據庫文件,而是經過主庫的binlog日誌複製到須要同步的從服務器上。
在複製的過程當中,一臺服務器充當主服務器(Master),接收來自用戶的內容更新,而一個或多個其餘的服務器充當從服務器(slave),接收來自Master上binlog文件的日誌內容,解析出SQL,從新更新到Slave,使得主從服務器數據達到一致。redis
主從複製的邏輯有如下幾種
一主一從,單向主從同步模式,只能在Master端寫入數據sql
一主多從數據庫
雙主主複製邏輯架構,此架構能夠在Master1或Master2進行數據寫入,或者兩端同時寫入(特殊設置)json
4.應用場景
利用複製功能當Master服務器出現問題時,咱們能夠人工的切換到從服務器繼續提供服務,此時服務器的數據和宕機時的數據幾乎徹底一致。
複製功能也可用做數據備份,可是若是人爲的執行drop,delete等語句刪除,那麼從庫的備份功能也就失效了vim
二、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 mariadb 2.在主庫建立用戶,用於同步數據 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.sql
5.確保數據導出後,沒有數據插入,完畢再查看主庫狀態centos
show master status;緩存
6.遠程傳輸主庫的數據,給從庫,進行導入 scp /tmp/db.sql root@192.168.3.27:/tmp/ 7.解鎖主庫的鎖,寫入數據,查看從庫是否同步 unlock tables;
三、從庫slave(192.168.3.27)機器的配置步驟
1.在從庫的 /etc/my.cnf中添加參數,添加只讀參數 [mysqld] server-id=3 read-only=true 2.重啓數據庫 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.000002 Slave_IO_Running: Yes Slave_SQL_Running: Yes 6.此時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.完成主從同步,讀寫分離實驗
3、redis基礎
redis是一種高級的key:value存儲系統,其中value支持五種數據類型
String: 字符串
Hash: 散列
List: 列表
Set: 集合
Sorted Set: 有序集合安全
一、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"
二、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"
三、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"
四、哈希數據結構
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
五、額外的危險操做(慎用)
獲取redis數據庫中全部的鍵(這個不危險) keys * 刪除全部Key,可使用Redis的flushdb和flushall命令(危險慎用) # 刪除當前數據庫中的全部Key flushdb # 刪除全部數據庫中的key flushall
4、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同時在線
5、redis數據持久化
redis的缺點:
redis數據放在內存中
重啓服務器丟失數據
重啓redis服務丟失數據
斷電丟失數據
爲了防止redis數據丟失,進行持久化,將數據,寫入到一個文件中
一、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-cli 127.0.0.1:6379> set age 18 OK 127.0.0.1:6379> save OK 5.進入/data/6379查看是否生成了 dbmp.rdb 持久化文件 注意:rdb數據文件是二進制文件,人爲的看不懂 6.kill掉redis進程,再重啓,進入redis keys * 查看數據是否還在
二、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 10000 appendonly yes appendfsync everysec 2,重啓redis數據庫,加載aof功能 會在/data/6379目錄下生成 appendonly.aof 文件 3,appendonly.aof 文件是人能夠看懂的記錄了sql操做的文件 4,測試 進入redis客戶端 redis-cli 127.0.0.1:6379> set long 18 OK 5,進入/data/6379查看appendonly.aof 文件的內容 6,kill掉redis進程,再重啓,進入redis keys * 查看數據是否還在
三、在不重啓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功能 OK 3.檢查此時的數據持久化方式是rdb,仍是aof,檢查appendonly.aof文件,數據變更 tail -f appendonly.aof 4.此時aof還未永久生效,寫入參數到配置文件 編輯redis-6379.conf 添加以下參數 appendonly yes appendfsync everysec
四、redis持久化方式有什麼區別
rdb:基於快照的持久化,速度更快,通常用做備份,主從複製也是依賴於rdb持久化功能
aof:以追加的方式記錄redis操做日誌的文件。能夠最大程度的保證redis數據安全,相似於mysql的binlog
6、redis主從同步實現
原理:
1. 從服務器向主服務器發送 SYNC 命令。
2. 接到 SYNC 命令的主服務器會調用BGSAVE 命令,建立一個 RDB 文件,並使用緩衝區記錄接下來執行的全部寫命令。
3. 當主服務器執行完 BGSAVE 命令時,它會向從服務器發送 RDB 文件,而從服務器則會接收並載入這個文件。
4. 主服務器將緩衝區儲存的全部寫命令發送給從服務器執行。
小知識:
1. 在開啓主從複製的時候,使用的是RDB方式的,同步主從數據的
2. 同步開始以後,經過主庫命令傳播的方式,主動的複製方式實現
3. 2.8之後實現PSYNC的機制,實現斷線重連
一、使用配置文件進行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 6379 2.啓動三個redis實例 redis-server redis-6379.conf redis-server redis-6380.conf redis-server redis-6381.conf 3.查看主從同步身份 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=1 2,redis-cli -p 6380 info replication # Replication role:slave master_host:127.0.0.1 master_port:6379 3,redis-cli -p 6381 info replication # Replication role:slave master_host:127.0.0.1 master_port:6379 4.測試 # 在6379主庫 redis-cli -p 6379 127.0.0.1:6379> set uzi good OK # 在6380從庫 redis-cli -p 6380 127.0.0.1:6380> get uzi "good" # 在6381從庫 redis-cli -p 6381 127.0.0.1:6381> get uzi "good"
二、使用命令行進行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
三、若是我主庫掛了怎麼辦
解決方案:手動切換主從身份,選舉一個新的主庫 1.幹掉6379主庫 redis-cli -p 6379 shutdown 2.在6380上關閉本身的slave身份 127.0.0.1:6380> slaveof no one 3.在6381上給與新的主人身份 127.0.0.1:6381> salveof 127.0.0.1 6380 4.修改完畢,還得修改配置文件,永久生效