各位老鐵們,大家有沒有想老張,最近老張的才華被工做的繁忙所限制了,因此一直沒時間更博,今兒個時隔很多天咱們終於再次見面啦(很開心)!最近有部特別火的宮廷戲,不知道你們有沒有看,劇名叫作《延禧攻略》,講述得是一個宮女,一路過關斬將,最後成爲皇上最寵愛的令貴妃的故事。加上我本人巨愛這類題材,因此癡迷得不得了。(好像暴露了本身沒有更博的真正緣由哈哈)。宮廷類的劇,都是後宮嬪妃之間的爾虞吾詐,勾心鬥角,有你沒我,有我沒你的殘酷事實。勝者爲王,敗者爲寇這種思想好像從古代就一直延續到今日。非要分出個勝負,分出個誰好,誰壞才罷休。mysql
在數據庫領域也會有此類問題,老張我混跡開源數據庫圈多年。MySQL數據庫佔領着開源數據庫的頭把交椅,MongoDB佔領着NoSQL數據庫的第一位。咱們來看下數據庫的總體排名狀況;sql
二者都是第一,全部總會拿來比較。也會常常被人問及到諸如此類的問題MongoDB4.0已經問世了,並且支持事務了,是否是未來能夠取代MySQL了。MySQL和MongoDB哪一個數據庫好用啊。今天老張想經過這篇文章,帶着你們全方位解讀MySQL與MongoDB的區別。讓有困惑的老鐵們明白,沒有誰替代誰,只有哪一個場景更適合誰。數據庫
咱們從下面四個方向依次闡明二者的區別。只有更瞭解彼此,讓能更好地利用它們的功能性。數組
咱們先來了解一下MySQL這個數據庫;服務器
再來學習一下MySQL數據庫的特色;數據結構
MySQL瞭解完,同理咱們來了解MongoDB及其特色的介紹;架構
MongoDB特色介紹:併發
學習完第一部分以後,咱們對二者數據庫都有了必定的認識;接下來去從運維的角度來檢驗二者的不一樣;運維
結論能夠看出,關係型數據庫中的表,在MongoDB中叫作集合。行在MongoDB中叫作文檔。因此常常管MongoDB叫作文檔型數據庫。異步
在關係型數據庫中設計表,有些信息須要多表記錄。
而在MongoDB中,上面的三張表,就變成下面的這一段代碼就能夠實現了。
{ _id:"M416", name:"zhangsu", phone:[1234,5678], ..... }
MongoDB表設計的特色
MySQL數據庫的配置叫作my.cnf,咱們來看下它的記錄方式;
[client] port = 3306 socket = /data/mysql/mysql.sock [mysql] prompt="\u@db \R:\m:\s [\d]> " no-auto-rehash [mysqld] user = mysql port = 3306 basedir = /usr/local/mysql datadir = /data/mysql/ socket = /data/mysql/mysql.sock pid-file = db.pid character-set-server = utf8mb4 skip_name_resolve = 1 open_files_limit = 65535 back_log = 1024 max_connections = 512 max_connect_errors = 1000000 table_open_cache = 1024 table_definition_cache = 1024 table_open_cache_instances = 64 thread_stack = 512K external-locking = FALSE max_allowed_packet = 32M sort_buffer_size = 4M join_buffer_size = 4M thread_cache_size = 768 #query_cache_size = 0 #query_cache_type = 0 interactive_timeout = 600 wait_timeout = 600 tmp_table_size = 32M max_heap_table_size = 32M slow_query_log = 1 slow_query_log_file = /data/mysql/slow.log log-error = /data/mysql/error.log long_query_time = 0.1 server-id = 3306101 log-bin = /data/mysql/mybinlog sync_binlog = 1 binlog_cache_size = 4M max_binlog_cache_size = 1G max_binlog_size = 1G expire_logs_days = 7 master_info_repository = TABLE relay_log_info_repository = TABLE gtid_mode = on enforce_gtid_consistency = 1 log_slave_updates=1 binlog_format = row relay_log_recovery = 1 relay-log-purge = 1 key_buffer_size = 32M read_buffer_size = 8M read_rnd_buffer_size = 4M bulk_insert_buffer_size = 64M #myisam_sort_buffer_size = 128M #myisam_max_sort_file_size = 10G #myisam_repair_threads = 1 lock_wait_timeout = 3600 explicit_defaults_for_timestamp = 1 innodb_thread_concurrency = 0 innodb_sync_spin_loops = 100 innodb_spin_wait_delay = 30 secure_file_priv='' super_read_only=0 transaction_isolation = REPEATABLE-READ #innodb_additional_mem_pool_size = 16M innodb_buffer_pool_size = 1024M innodb_buffer_pool_instances = 8 innodb_buffer_pool_load_at_startup = 1 innodb_buffer_pool_dump_at_shutdown = 1 innodb_data_file_path = ibdata1:100M:autoextend innodb_flush_log_at_trx_commit = 1 innodb_log_buffer_size = 32M innodb_log_file_size = 2G innodb_log_files_in_group = 2 innodb_max_undo_log_size = 4G innodb_io_capacity = 4000 innodb_io_capacity_max = 8000 innodb_flush_neighbors = 0 innodb_write_io_threads = 8 innodb_read_io_threads = 8 innodb_purge_threads = 4 innodb_page_cleaners = 4 innodb_open_files = 65535 innodb_max_dirty_pages_pct = 50 innodb_flush_method = O_DIRECT innodb_lru_scan_depth = 4000 innodb_checksum_algorithm = crc32 #innodb_file_format = Barracuda #innodb_file_format_max = Barracuda innodb_lock_wait_timeout = 10 innodb_rollback_on_timeout = 1 innodb_print_all_deadlocks = 1 innodb_file_per_table = 1 innodb_online_alter_log_max_size = 4G internal_tmp_disk_storage_engine = InnoDB innodb_stats_on_metadata = 0 innodb_status_file = 1 [mysqldump] quick max_allowed_packet = 32M
MongoDB配置文件使用Yaml格式
但隨着MongoDB 4.0的問世,它將支持多文檔事務,屆時MongoDB將成爲惟一可以同時支持速度,靈活性,JSON文檔模型優點 和ACID數據完整性保證的數據庫。
所謂的多文檔事務,能夠理解爲關係型數據庫的多行事務。在關係型的事務支持中,你們幾乎無一例外支持同一事務內操做的原子性,即要麼所有提交,要麼所有回滾。這個同一事務內能夠有多個操做,針對於多個表,或者是同一個表內的多行數據。
總結:隨着事務支持的增長,MongoDB功能上更接近於關係型數據庫,可是和關係型仍是有本質上的區別:MySQL是基於關係模型的數據庫,對各類數據多變的場景如物聯網或社交化並無MongoDB支持得好。MongoDB的JSON模型則具備動態靈活,數據庫無須下線就能夠進行模式變遷升級,在這種場景下面,選擇MongoDB會特別合適。
MySQL備份方式:
MongoDB備份方式:
邏輯備份與恢復
1.mongodump
2.mongorestore
3.mongoexport
4.mongoimport
注:MongoDB目前爲止尚未像xtrabackup這種好用的備份工具。因此通常來講,都是使用邏輯備份方式來進行操做
從運維角度咱們對它們有了更深的認識以後,咱們來從集羣架構的維度出發,去探究其更深的不一樣之處。
咱們先從MySQL複製的角度入手;而後再介紹MySQL高可用集羣架構
MySQL主從複製原理圖
MySQL複製種類總結;
異步複製:
一般沒說明指的都是異步,即主庫執行完Commit後,在主庫寫入Binlog日誌後便可成功返回客戶端,無需等Binlog日誌傳送給從庫,一旦主庫宕機,有可能會丟失日誌。
半同步複製:MySQL5.5版本以後引入了半同步複製功能,主從服務器必須同時安裝半同步複製插件,才能開啓該複製功能。在該功能下,確保從庫接收完主庫傳遞過來的binlog內容已經寫入到本身的relay log裏面了,纔會通知主庫上面的等待線程,該操做完畢。若是等待超時,超過rpl_semi_sync_master_timeout參數設置的時間,則關閉半同步複製,並自動轉換爲異步複製模式,直到至少有一臺從庫通知主庫已經接收到binlog信息了爲止。
多源複製:
所謂多源複製,就是把多臺主庫的數據同步到一臺從庫服務器上,從庫會建立通往每一個主庫的管道。在MySQL5.7以前的版本中,只能實現一主一從、一主多從或者多主多從的複製架構,若是想要實現多主一從的複製,只能使用MariaDB。MySQL 5.7版本已經能夠實現多主一從的複製。
並行複製:
使用MySQL5.7的並行複製功能。在5.6版本中就有了並行的概念,但其中的並行複製是基於庫級別的,即slave_parallel_type=database。但在這種模式下,只是基於多庫少表的狀況,並不適用於真實的生產環境下。在MySQL 5.7版本中,真正實現了基於組提交的並行複製,簡單說就是主庫並行執行SQL語句,從庫也能夠經過多個workers線程併發執行relay log中主庫提交的事務。想要開啓MySQL5.7的並行複製能夠在從庫設置參數slave_parallel_workers>0,並把5.7版本中新添加的slave_parallel_type參數設置爲LOGICAL_CLOCK。該參數有DATABASE和 LOGICAL_CLOCK兩個值。MySQL5.6默認是database。
MySQL高可用集羣架構分類圖;
MHA:
MHA的目的在於維持MySQL Replication中master庫的高可用性,其最大特色是能夠修復多個slave之間的差別日誌,最終使全部slave保持數據一致,而後從中選擇一個充當新的master,並將其餘slave指向它。當master出現故障時,能夠經過對比slave之間I/O thread 讀取主庫binlog的position號,選取最接近的slave做爲備選主庫(備胎)。其餘的從庫能夠經過與備選主庫對比生成差別的中繼日誌。在備選主庫上應用從原來master保存的binlog,同時將備選主庫提高爲master。最後在其餘slave上應用相應的差別中繼日誌並重新的master開始複製。
雙主+keepalived
中小型規模的時候,採用這種架構是最省事的。
兩個節點能夠採用簡單的一主一從模式,或者雙主模式,而且放置於同一個VLAN中,在master節點發生故障後,利用keepalived/heartbeat的高可用機制實現快速切換到slave節點。
PXC集羣:
PXC是基於Galera協議的MySQL高可用集羣架構。Galera產品是以Galera Cluster方式爲MySQL提供高可用集羣解決方案的。Galera Cluster就是集成了Galera插件的MySQL集羣。Galera replication是Codership提供的MySQL數據同步方案,具備高可用性,方便擴展,而且能夠實現多個MySQL節點間的數據同步複製與讀寫,可保障數據庫的服務高可用及數據強一致性。
MGR架構:
MySQL官方在5.7.17版本正式推出組複製(MySQL Group Replication,簡稱MGR)。master1,master2,master3,全部成員獨立完成各自的事務。當客戶端先發起一個更新事務,該事務先在本地執行,執行完成以後就要發起對事務的提交操做了。在尚未真正提交以前須要將產生的複製寫集廣播出去,複製到其餘成員。若是衝突檢測成功,組內決定該事務能夠提交,其餘成員能夠應用,不然就回滾。最終,這意味着全部組內成員以相同的順序接收同一組事務。所以組內成員以相同的順序應用相同的修改,保證組內數據強一致性。
接下來介紹MongoDB的複製狀況;
MongoDB複製集:
三副本架構是最基礎的複製集的架構,一主兩備模式。主節點接受外界的讀寫請求,向備節點進行數據同步。當主節點宕掉,會自動切換到備節點,不影響線上業務,防止單點故障。
MongoDB複製集自動切換
副本集的全部成員均可以接受讀取操做。 可是,默認狀況下,應用程序將其讀取操做指向primary。
副本集能夠有至多一個primary節點,primary節點宕機後,集羣會觸發選舉以選出新的primary節點
在如下三成員節點副本集架構中,primary宕機後,觸發了一次選舉,從剩下的兩個secondary節點裏,選舉出了一個新的primary節點。
MongoDB複製集讀寫分離設置
read preference 決定MongoDB客戶端從哪一個節點上讀取數據。
默認狀況下,應用程序將其讀取操做指向副本集中的primary節點。
指定read preference 選項時要注意:由於使用異步複製,複製延遲會致使secondary上的數據可能不是最新的。
默認狀況下,複製集的全部讀請求都發到Primary,Driver可經過設置Read Preference來將讀請求路由到其餘的節點。
primary: 默認規則,全部讀請求發到Primary
primaryPreferred: Primary優先,若是Primary不可達,請求Secondary
secondary: 全部的讀請求都發到secondary
secondaryPreferred:Secondary優先,當全部Secondary不可達時,請求Primary
nearest:讀請求發送到最近的可達節點上(經過ping探測得出最近的節點)
MongoDB分片架構
分片是一種在多臺機器上分配數據的方法。 MongoDB使用分片架構有助於您去管理很是大數量的數據集和高吞吐量操做的集羣。
大數據量和高吞吐量的業務狀況對單臺服務器來說是具有很大的挑戰性的。例如,高查詢率可能耗盡服務器的CPU容量。工做集大小超過系統內存,那麼壓力則會給到磁盤上,這對IO來說不是咱們所但願看到的。
MongoDB支持經過分片進行水平縮放。
總結:MySQL的複製種類不少,集羣架構在選擇性上來講也比較多。但橫向擴展能力上,沒有MongoDB的分片架構擴展能力強。
最後一部分,咱們來經過MySQL與MongoDB的不一樣應用場景;來對兩種數據庫作一個最後的總結;
正如開篇介紹MySQL特色時說的,MySQL使用得覆蓋率已經接近100%。從大型BAT,電商平臺,遊戲公司,甚至諸多傳統行業也無不例外都在往MySQL數據庫方向靠攏,達到逐漸壟斷的趨勢。對於MongoDB 的應用也已經×××到各個領域,好比遊戲、物流、電商、內容管理、社交、物聯網、視頻直播等。
2.物流場景:使用MongoDB存儲訂單信息,訂單狀態在運送過程當中會不斷更新,以MongoDB內嵌數組的形式來存儲,一次查詢就能將訂單全部的變動讀取出來。
3.社交場景:使用MongoDB存儲用戶信息,以及用戶發表的朋友圈信息,經過地理位置索引實現附近的人、地點等功能
4.物聯網場景:使用MongoDB存儲全部接入的智能設備信息,以及設備彙報的日誌信息,並對這些信息進行多維度的分析
對我而言,2009年開始接觸MySQL,我在2012年接觸的MongoDB的第一個版本2.1,對於這兩個數據庫真是手心手背都是肉。在我孤獨寂寞的時候,都是它們一直陪伴着我,感謝技術給咱們帶來的簡單快樂。不管將來發展如何,沒有所謂的誰會替代誰,只是說它們各自都有不一樣的特色,促使在不一樣的應用場景下,咱們使用誰更合適而已。這裏沒有宮廷內鬥,沒有爾虞我詐,只有那份最簡單地作技術的心,是現實版的延禧攻略!
對老張而言,寫篇文章很簡單,但真得但願能夠幫助到那些剛入門或者想深刻學習數據庫的同窗們。能力有限,水平通常,哪裏有介紹不到的地方,還望你們海涵!
在咱們最愛的51CTO 13歲生日之際,做爲51CTO專家博主,數據庫專家,我推出了本身的訂閱專欄十年老兵教你練一套正宗的MySQL降龍十八掌