您好,登錄后才能下訂單哦!
各位老鐵們,你們有沒(méi)有想老張,最近老張的才華被工作的繁忙所限制了,所以一直沒(méi)時(shí)間更博,今兒個(gè)時(shí)隔數(shù)日我們終于再次見(jiàn)面啦(很開(kāi)心)!最近有部特別火的宮廷戲,不知道大家有沒(méi)有看,劇名叫做《延禧攻略》,講述得是一個(gè)宮女,一路過(guò)關(guān)斬將,最后成為皇上最寵愛(ài)的令貴妃的故事。加上我本人巨愛(ài)這類(lèi)題材,所以癡迷得不得了。(好像暴露了自己沒(méi)有更博的真正原因哈哈)。宮廷類(lèi)的劇,都是后宮嬪妃之間的爾虞吾詐,勾心斗角,有你沒(méi)我,有我沒(méi)你的殘酷事實(shí)。勝者為王,敗者為寇這種思想好像從古代就一直延續(xù)到今日。非要分出個(gè)勝負(fù),分出個(gè)誰(shuí)好,誰(shuí)壞才罷休。
在數(shù)據(jù)庫(kù)領(lǐng)域也會(huì)有此類(lèi)問(wèn)題,老張我混跡開(kāi)源數(shù)據(jù)庫(kù)圈多年。MySQL數(shù)據(jù)庫(kù)占領(lǐng)著開(kāi)源數(shù)據(jù)庫(kù)的頭把交椅,MongoDB占領(lǐng)著NoSQL數(shù)據(jù)庫(kù)的第一位。我們來(lái)看下數(shù)據(jù)庫(kù)的整體排名情況;
兩者都是第一,所有總會(huì)拿來(lái)比較。也會(huì)經(jīng)常被人問(wèn)及到諸如此類(lèi)的問(wèn)題MongoDB4.0已經(jīng)問(wèn)世了,而且支持事務(wù)了,是不是將來(lái)可以取代MySQL了。MySQL和MongoDB哪個(gè)數(shù)據(jù)庫(kù)好用啊。今天老張想通過(guò)這篇文章,帶著大家全方位解讀MySQL與MongoDB的區(qū)別。讓有困惑的老鐵們明白,沒(méi)有誰(shuí)替代誰(shuí),只有哪個(gè)場(chǎng)景更適合誰(shuí)。
我們從下面四個(gè)方向依次闡明兩者的區(qū)別。只有更了解彼此,讓能更好地利用它們的功能性。
我們先來(lái)了解一下MySQL這個(gè)數(shù)據(jù)庫(kù);
再來(lái)學(xué)習(xí)一下MySQL數(shù)據(jù)庫(kù)的特點(diǎn);
MySQL了解完,同理我們來(lái)了解MongoDB及其特點(diǎn)的介紹;
MongoDB特點(diǎn)介紹:
學(xué)習(xí)完第一部分之后,我們對(duì)兩者數(shù)據(jù)庫(kù)都有了一定的認(rèn)識(shí);接下來(lái)去從運(yùn)維的角度來(lái)檢驗(yàn)兩者的不同;
結(jié)論可以看出,關(guān)系型數(shù)據(jù)庫(kù)中的表,在MongoDB中叫做集合。行在MongoDB中叫做文檔。所以經(jīng)常管MongoDB叫做文檔型數(shù)據(jù)庫(kù)。
在關(guān)系型數(shù)據(jù)庫(kù)中設(shè)計(jì)表,有些信息需要多表記錄。
而在MongoDB中,上面的三張表,就變成下面的這一段代碼就可以實(shí)現(xiàn)了。
{
_id:"M416",
name:"zhangsu",
phone:[1234,5678],
.....
}
MongoDB表設(shè)計(jì)的特點(diǎn)
MySQL數(shù)據(jù)庫(kù)的配置叫做my.cnf,我們來(lái)看下它的記錄方式;
[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的問(wèn)世,它將支持多文檔事務(wù),屆時(shí)MongoDB將成為唯一能夠同時(shí)支持速度,靈活性,JSON文檔模型優(yōu)勢(shì) 和ACID數(shù)據(jù)完整性保證的數(shù)據(jù)庫(kù)。
所謂的多文檔事務(wù),可以理解為關(guān)系型數(shù)據(jù)庫(kù)的多行事務(wù)。在關(guān)系型的事務(wù)支持中,大家?guī)缀鯚o(wú)一例外支持同一事務(wù)內(nèi)操作的原子性,即要么全部提交,要么全部回滾。這個(gè)同一事務(wù)內(nèi)可以有多個(gè)操作,針對(duì)于多個(gè)表,或者是同一個(gè)表內(nèi)的多行數(shù)據(jù)。
總結(jié):隨著事務(wù)支持的增加,MongoDB功能上更接近于關(guān)系型數(shù)據(jù)庫(kù),但是和關(guān)系型還是有本質(zhì)上的區(qū)別:MySQL是基于關(guān)系模型的數(shù)據(jù)庫(kù),對(duì)各種數(shù)據(jù)多變的場(chǎng)景如物聯(lián)網(wǎng)或社交化并沒(méi)有MongoDB支持得好。MongoDB的JSON模型則具有動(dòng)態(tài)靈活,數(shù)據(jù)庫(kù)無(wú)須下線就可以進(jìn)行模式變遷升級(jí),在這種場(chǎng)景下面,選擇MongoDB會(huì)特別合適。
MySQL備份方式:
MongoDB備份方式:
邏輯備份與恢復(fù)
1.mongodump
2.mongorestore
3.mongoexport
4.mongoimport
注:MongoDB目前為止還沒(méi)有像xtrabackup這種好用的備份工具。所以一般來(lái)說(shuō),都是使用邏輯備份方式來(lái)進(jìn)行操作
從運(yùn)維角度我們對(duì)它們有了更深的認(rèn)識(shí)之后,我們來(lái)從集群架構(gòu)的維度出發(fā),去探究其更深的不同之處。
我們先從MySQL復(fù)制的角度入手;然后再介紹MySQL高可用集群架構(gòu)
MySQL主從復(fù)制原理圖
MySQL復(fù)制種類(lèi)總結(jié);
異步復(fù)制:
通常沒(méi)說(shuō)明指的都是異步,即主庫(kù)執(zhí)行完Commit后,在主庫(kù)寫(xiě)入Binlog日志后即可成功返回客戶端,無(wú)需等Binlog日志傳送給從庫(kù),一旦主庫(kù)宕機(jī),有可能會(huì)丟失日志。
半同步復(fù)制:MySQL5.5版本之后引入了半同步復(fù)制功能,主從服務(wù)器必須同時(shí)安裝半同步復(fù)制插件,才能開(kāi)啟該復(fù)制功能。在該功能下,確保從庫(kù)接收完主庫(kù)傳遞過(guò)來(lái)的binlog內(nèi)容已經(jīng)寫(xiě)入到自己的relay log里面了,才會(huì)通知主庫(kù)上面的等待線程,該操作完畢。如果等待超時(shí),超過(guò)rpl_semi_sync_master_timeout參數(shù)設(shè)置的時(shí)間,則關(guān)閉半同步復(fù)制,并自動(dòng)轉(zhuǎn)換為異步復(fù)制模式,直到至少有一臺(tái)從庫(kù)通知主庫(kù)已經(jīng)接收到binlog信息了為止。
多源復(fù)制:
所謂多源復(fù)制,就是把多臺(tái)主庫(kù)的數(shù)據(jù)同步到一臺(tái)從庫(kù)服務(wù)器上,從庫(kù)會(huì)創(chuàng)建通往每個(gè)主庫(kù)的管道。在MySQL5.7之前的版本中,只能實(shí)現(xiàn)一主一從、一主多從或者多主多從的復(fù)制架構(gòu),如果想要實(shí)現(xiàn)多主一從的復(fù)制,只能使用MariaDB。MySQL 5.7版本已經(jīng)可以實(shí)現(xiàn)多主一從的復(fù)制。
并行復(fù)制:
使用MySQL5.7的并行復(fù)制功能。在5.6版本中就有了并行的概念,但其中的并行復(fù)制是基于庫(kù)級(jí)別的,即slave_parallel_type=database。但在這種模式下,只是基于多庫(kù)少表的情況,并不適用于真實(shí)的生產(chǎn)環(huán)境下。在MySQL 5.7版本中,真正實(shí)現(xiàn)了基于組提交的并行復(fù)制,簡(jiǎn)單說(shuō)就是主庫(kù)并行執(zhí)行SQL語(yǔ)句,從庫(kù)也可以通過(guò)多個(gè)workers線程并發(fā)執(zhí)行relay log中主庫(kù)提交的事務(wù)。想要開(kāi)啟MySQL5.7的并行復(fù)制可以在從庫(kù)設(shè)置參數(shù)slave_parallel_workers>0,并把5.7版本中新添加的slave_parallel_type參數(shù)設(shè)置為L(zhǎng)OGICAL_CLOCK。該參數(shù)有DATABASE和 LOGICAL_CLOCK兩個(gè)值。MySQL5.6默認(rèn)是database。
MySQL高可用集群架構(gòu)分類(lèi)圖;
MHA:
MHA的目的在于維持MySQL Replication中master庫(kù)的高可用性,其最大特點(diǎn)是可以修復(fù)多個(gè)slave之間的差異日志,最終使所有slave保持?jǐn)?shù)據(jù)一致,然后從中選擇一個(gè)充當(dāng)新的master,并將其他slave指向它。當(dāng)master出現(xiàn)故障時(shí),可以通過(guò)對(duì)比slave之間I/O thread 讀取主庫(kù)binlog的position號(hào),選取最接近的slave作為備選主庫(kù)(備胎)。其他的從庫(kù)可以通過(guò)與備選主庫(kù)對(duì)比生成差異的中繼日志。在備選主庫(kù)上應(yīng)用從原來(lái)master保存的binlog,同時(shí)將備選主庫(kù)提升為master。最后在其他slave上應(yīng)用相應(yīng)的差異中繼日志并從新的master開(kāi)始復(fù)制。
雙主+keepalived
中小型規(guī)模的時(shí)候,采用這種架構(gòu)是最省事的。
兩個(gè)節(jié)點(diǎn)可以采用簡(jiǎn)單的一主一從模式,或者雙主模式,并且放置于同一個(gè)VLAN中,在master節(jié)點(diǎn)發(fā)生故障后,利用keepalived/heartbeat的高可用機(jī)制實(shí)現(xiàn)快速切換到slave節(jié)點(diǎn)。
PXC集群:
PXC是基于Galera協(xié)議的MySQL高可用集群架構(gòu)。Galera產(chǎn)品是以Galera Cluster方式為MySQL提供高可用集群解決方案的。Galera Cluster就是集成了Galera插件的MySQL集群。Galera replication是Codership提供的MySQL數(shù)據(jù)同步方案,具有高可用性,方便擴(kuò)展,并且可以實(shí)現(xiàn)多個(gè)MySQL節(jié)點(diǎn)間的數(shù)據(jù)同步復(fù)制與讀寫(xiě),可保障數(shù)據(jù)庫(kù)的服務(wù)高可用及數(shù)據(jù)強(qiáng)一致性。
MGR架構(gòu):
MySQL官方在5.7.17版本正式推出組復(fù)制(MySQL Group Replication,簡(jiǎn)稱(chēng)MGR)。master1,master2,master3,所有成員獨(dú)立完成各自的事務(wù)。當(dāng)客戶端先發(fā)起一個(gè)更新事務(wù),該事務(wù)先在本地執(zhí)行,執(zhí)行完成之后就要發(fā)起對(duì)事務(wù)的提交操作了。在還沒(méi)有真正提交之前需要將產(chǎn)生的復(fù)制寫(xiě)集廣播出去,復(fù)制到其他成員。如果沖突檢測(cè)成功,組內(nèi)決定該事務(wù)可以提交,其他成員可以應(yīng)用,否則就回滾。最終,這意味著所有組內(nèi)成員以相同的順序接收同一組事務(wù)。因此組內(nèi)成員以相同的順序應(yīng)用相同的修改,保證組內(nèi)數(shù)據(jù)強(qiáng)一致性。
接下來(lái)介紹MongoDB的復(fù)制情況;
MongoDB復(fù)制集:
三副本架構(gòu)是最基礎(chǔ)的復(fù)制集的架構(gòu),一主兩備模式。主節(jié)點(diǎn)接受外界的讀寫(xiě)請(qǐng)求,向備節(jié)點(diǎn)進(jìn)行數(shù)據(jù)同步。當(dāng)主節(jié)點(diǎn)宕掉,會(huì)自動(dòng)切換到備節(jié)點(diǎn),不影響線上業(yè)務(wù),防止單點(diǎn)故障。
MongoDB復(fù)制集自動(dòng)切換
副本集的所有成員都可以接受讀取操作。 但是,默認(rèn)情況下,應(yīng)用程序?qū)⑵渥x取操作指向primary。
副本集可以有至多一個(gè)primary節(jié)點(diǎn),primary節(jié)點(diǎn)宕機(jī)后,集群會(huì)觸發(fā)選舉以選出新的primary節(jié)點(diǎn)
在以下三成員節(jié)點(diǎn)副本集架構(gòu)中,primary宕機(jī)后,觸發(fā)了一次選舉,從剩下的兩個(gè)secondary節(jié)點(diǎn)里,選舉出了一個(gè)新的primary節(jié)點(diǎn)。
MongoDB復(fù)制集讀寫(xiě)分離設(shè)置
read preference 決定MongoDB客戶端從哪個(gè)節(jié)點(diǎn)上讀取數(shù)據(jù)。
默認(rèn)情況下,應(yīng)用程序?qū)⑵渥x取操作指向副本集中的primary節(jié)點(diǎn)。
指定read preference 選項(xiàng)時(shí)要注意:因?yàn)槭褂卯惒綇?fù)制,復(fù)制延遲會(huì)導(dǎo)致secondary上的數(shù)據(jù)可能不是最新的。
默認(rèn)情況下,復(fù)制集的所有讀請(qǐng)求都發(fā)到Primary,Driver可通過(guò)設(shè)置Read Preference來(lái)將讀請(qǐng)求路由到其他的節(jié)點(diǎn)。
primary: 默認(rèn)規(guī)則,所有讀請(qǐng)求發(fā)到Primary
primaryPreferred: Primary優(yōu)先,如果Primary不可達(dá),請(qǐng)求Secondary
secondary: 所有的讀請(qǐng)求都發(fā)到secondary
secondaryPreferred:Secondary優(yōu)先,當(dāng)所有Secondary不可達(dá)時(shí),請(qǐng)求Primary
nearest:讀請(qǐng)求發(fā)送到最近的可達(dá)節(jié)點(diǎn)上(通過(guò)ping探測(cè)得出最近的節(jié)點(diǎn))
MongoDB分片架構(gòu)
分片是一種在多臺(tái)機(jī)器上分配數(shù)據(jù)的方法。 MongoDB使用分片架構(gòu)有助于您去管理非常大數(shù)量的數(shù)據(jù)集和高吞吐量操作的集群。
大數(shù)據(jù)量和高吞吐量的業(yè)務(wù)情況對(duì)單臺(tái)服務(wù)器來(lái)講是具備很大的挑戰(zhàn)性的。例如,高查詢率可能耗盡服務(wù)器的CPU容量。工作集大小超過(guò)系統(tǒng)內(nèi)存,那么壓力則會(huì)給到磁盤(pán)上,這對(duì)IO來(lái)講不是我們所希望看到的。
MongoDB支持通過(guò)分片進(jìn)行水平縮放。
總結(jié):MySQL的復(fù)制種類(lèi)很多,集群架構(gòu)在選擇性上來(lái)說(shuō)也比較多。但橫向擴(kuò)展能力上,沒(méi)有MongoDB的分片架構(gòu)擴(kuò)展能力強(qiáng)。
最后一部分,我們來(lái)通過(guò)MySQL與MongoDB的不同應(yīng)用場(chǎng)景;來(lái)對(duì)兩種數(shù)據(jù)庫(kù)做一個(gè)最后的總結(jié);
正如開(kāi)篇介紹MySQL特點(diǎn)時(shí)說(shuō)的,MySQL使用得覆蓋率已經(jīng)接近100%。從大型BAT,電商平臺(tái),游戲公司,甚至諸多傳統(tǒng)行業(yè)也無(wú)不例外都在往MySQL數(shù)據(jù)庫(kù)方向靠攏,達(dá)到逐漸壟斷的趨勢(shì)。對(duì)于MongoDB 的應(yīng)用也已經(jīng)×××到各個(gè)領(lǐng)域,比如游戲、物流、電商、內(nèi)容管理、社交、物聯(lián)網(wǎng)、視頻直播等。
2.物流場(chǎng)景:使用MongoDB存儲(chǔ)訂單信息,訂單狀態(tài)在運(yùn)送過(guò)程中會(huì)不斷更新,以MongoDB內(nèi)嵌數(shù)組的形式來(lái)存儲(chǔ),一次查詢就能將訂單所有的變更讀取出來(lái)。
3.社交場(chǎng)景:使用MongoDB存儲(chǔ)用戶信息,以及用戶發(fā)表的朋友圈信息,通過(guò)地理位置索引實(shí)現(xiàn)附近的人、地點(diǎn)等功能
4.物聯(lián)網(wǎng)場(chǎng)景:使用MongoDB存儲(chǔ)所有接入的智能設(shè)備信息,以及設(shè)備匯報(bào)的日志信息,并對(duì)這些信息進(jìn)行多維度的分析
對(duì)我而言,2009年開(kāi)始接觸MySQL,我在2012年接觸的MongoDB的第一個(gè)版本2.1,對(duì)于這兩個(gè)數(shù)據(jù)庫(kù)真是手心手背都是肉。在我孤獨(dú)寂寞的時(shí)候,都是它們一直陪伴著我,感謝技術(shù)給我們帶來(lái)的簡(jiǎn)單快樂(lè)。無(wú)論未來(lái)發(fā)展如何,沒(méi)有所謂的誰(shuí)會(huì)替代誰(shuí),只是說(shuō)它們各自都有不同的特點(diǎn),促使在不同的應(yīng)用場(chǎng)景下,我們使用誰(shuí)更合適而已。這里沒(méi)有宮廷內(nèi)斗,沒(méi)有爾虞我詐,只有那份最簡(jiǎn)單地做技術(shù)的心,是現(xiàn)實(shí)版的延禧攻略!
對(duì)老張而言,寫(xiě)篇文章很簡(jiǎn)單,但真得希望可以幫助到那些剛?cè)腴T(mén)或者想深入學(xué)習(xí)數(shù)據(jù)庫(kù)的同學(xué)們。能力有限,水平一般,哪里有介紹不到的地方,還望大家海涵!
在我們最?lèi)?ài)的51CTO 13歲生日之際,作為51CTO專(zhuān)家博主,數(shù)據(jù)庫(kù)專(zhuān)家,我推出了自己的訂閱專(zhuān)欄十年老兵教你練一套正宗的MySQL降龍十八掌
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。