当前位置: 首页 > 科技观察

数据库世界的《延禧攻略》来了,不看就输了

时间:2023-03-18 22:37:40 科技观察

【.com原创稿件】我个人很喜欢这种题材,所以迷恋上了。(好像暴露了我不多写博客的真正原因哈哈)。宫廷剧都是后宫妃子之间的尔虞我诈,尔虞我诈,有你无我,有我无你的残酷事实。胜者为王,败者为寇的观念似乎从古至今一直延续着。我们必须决定谁赢谁输,谁好谁坏。数据库领域也会有这样的问题。在开源数据库圈混了很多年。MySQL数据库占据开源数据库榜首,MongoDB占据NoSQL数据库榜首。再来看看数据库的综合排名:两者都是最好的,所以总会被比较。人们经常会被问到这样的问题。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=3306socket=/data/mysql/mysql.sock[mysql]prompt="\u@db\R:\m:\s[\d]>"no-auto-rehash[mysqld]user=mysqlport=3306basedir=/usr/local/mysqldatadir=/data/mysql/socket=/data/mysql/mysql.sockpid-file=db。pidcharacter-set-server=utf8mb4skip_name_resolve=1open_files_limit=65535back_log=1024max_connections=512max_connect_errors=1000000table_open_cache=1024table_definition_cache=1024table_open_cache_instances=64thread_stack=512Kexternal-locking=FALSEmax_allowed_pa??cket=32Msort_buffer_size=4Mjoin_buffer_size=4Mthread_cache_size=768#query_cache_size=0#query_cache_type=0interactive_timeout=600wait_timeout=600tmp_table_size=32Mmax_heap_table_size=32Mslow_query_log=1slow_query_log_file=/data/mysql/slow.loglog-error=/data/mysql/error.loglong_query_time=0.1server-id=3306101log-bin=/data/mysql/mybinlogsync_binlog=1binlog_cache_size=4Mmax_binlog_cache_size=1Gmax_binlog_size=1Gexpire_logs_days=7master_info_repository=TABLErelay_log_info_repository=TABLEgtid_mode=onenforce_gtid_consistency=1log_slave_updates=1binlog_format=rowrelay_log_recovery=1relay-log-purge=1key_buffer_size=32Mread_buffer_size=8Mread_rnd_buffer_size=4Mbulk_insert_buffer_size=64M#myisam_sort_buffer_size=128M#myisam_max_sort_file_size=10G#myisam_repair_threads=1lock_wait_timeout=3600explicit_defaults_for_timestamp=1innodb_thread_concurrency=0innodb_sync_spin_loops=100innodb_spin_wait_delay=30secure_file_priv=''super_read_only=0transaction_isolation=REPEATABLE-READ#innodb_additional_mem_pool_size=16Minnodb_buffer_pool_size=1024Minnodb_buffer_pool_instances=8innodb_buffer_pool_load_at_startup=1innodb_buffer_pool_dump_at_shutdown=1innodb_data_file_path=ibdata1:100M:autoextendinnodb_flush_log_at_trx_commit=1innodb_log_buffer_size=32Minnodb_log_file_size=2Ginnodb_log_files_in_group=2innodb_max_undo_log_size=4Ginnodb_io_capacity=4000innodb_io_capacity_max=8000innodb_flush_neighbors=0innodb_write_io_threads=8innodb_read_io_threads=8innodb_purge_threads=4innodb_page_cleaners=4innodb_open_files=65535innodb_max_dirty_pages_pct=50innodb_flush_method=O_DIRECTinnodb_lru_scan_depth=4000innodb_checksum_algorithm=crc32#innodb_file_format=Barracuda#innodb_file_format_max=Barracudainnodb_lock_wait_timeout=10innodb_rollback_on_timeout=1innodb_print_all_deadlocks=1innodb_file_per_table=1innodb_online_alter_log_max_size=4Ginternal_tmp_disk_storage_engine=InnoDBinnodb_stats_on_metadata=0innodb_status_file=1[mysqldump]quickmax_allowed_pa??cket=32MMongoDB配置文件使用Yaml格式,如下图:区别增删改查操作支持差异但是随着MongoDB4.0的到来,将支持多文档事务,然后MongoDB将成为唯一一个可以同时处理事务的数据库在支持速度、灵活性、JSON文档模型和ACID数据完整性保证的情况下,所谓的多文档事务可以理解为关系数据库中的多行事务。在关系事务支持上,几乎无一例外,大家都支持同一个事务内操作的原子性,即要么全部提交,要么全部回滚。同一个事务中可以有多个操作,针对多个表,或者同一个表中的多行数据。小结:随着事务支持的增加,MongoDB在功能上更接近于关系型数据库,但与关系型数据库还是有本质的区别。MySQL是一个基于关系模型的数据库,对于物联网、社交等各种数据变化场景,它对MongoDB的支持不是很好。MongoDB的JSON模型动态灵活,无需下线即可升级数据库。在这种场景下,MongoDB特别适合。备份MySQL备份方式的区别,如下图所示:MongoDB备份方式(逻辑备份与恢复):mongodumpmongorestoremongoexportmongoimport注意:MongoDB目前还没有xtrabackup这么好用的备份工具。所以一般都是采用逻辑备份来操作。在我们从运维的角度对它们有了更深入的了解之后,我们就从集群架构的维度出发,来探究更深层次的差异。集群架构层面的差异我们先从MySQL复制的角度出发,再介绍MySQL高可用集群架构。MySQL主从复制示意图如下:MySQL复制类型总结异步复制:通常没有说明是指异步复制,即主库执行Commit后,可以成功返回到主库client在主库写入Binlog日志后,不等待Binlog日志发送到从库。一旦主库宕机,日志可能会丢失。半同步复制:MySQL5.5之后引入了半同步复制功能。主从服务器必须同时安装半同步复制插件才能开启复制功能。在这个函数下,保证主库传过来的Binlog内容已经从从库接收到,并写入自己的RelayLog,然后通知主库上的等待线程操作完成。如果等待超时超过rpl_semi_sync_master_timeout参数设置的时间,半同步复制将被关闭,自动切换到异步复制模式,直到至少有一个从库通知主库它已经收到Binlog信息。多源复制:所谓多源复制,就是将多个主库的数据同步到一个从库服务器上,从库会创建一个管道到各个主库。MySQL5.7之前的版本只能实现一主从、一主多从、多主多从复制架构。如果要实现多主一从复制,只能使用MariaDB。MySQL5.7版本已经可以实现多主单从复制。并行复制:使用MySQL5.7的并行复制特性。在5.6版本中,有并行的概念,但其并行复制是基于库级别的,即slave_parallel_type=database。这种模式只是基于多库少表的情况,并不适合真实的生产环境。在MySQL5.7版本中,真正实现了基于组提交的并行复制。简单的说,主库并行执行SQL语句,从库也可以通过多个Workers线程,并发执行主库在RelayLog中提交的事务。如果要开启MySQL5.7的并行复制,可以在从库中设置参数slave_parallel_workers>0。并将5.7版本新增的slave_parallel_type参数设置为LOGICAL_CLOCK。这个参数有两个值DATABASE和LOGICAL_CLOCK。MySQL5.6默认为数据库。MySQL高可用集群架构MySQL高可用集群架构分类图如下:MHAMHA集群架构图MHA的目的是维护MySQLReplication中Master库的高可用。它最大的特点是可以修复多个Slave之间的差异日志。让所有Slave保持数据一致,然后选择其中一个作为新的Master,将其他Slave指向它。当Master发生故障时,可以通过比较Slaves之间的I/O线程,读取主库Binlog的Position编号,选择距离最近的Slave作为备份主库(备胎)。其他从库可以通过与备选主库进行比较,产生差异中继日志。将原Master保存的Binlog应用到备用主库上,同时将备用主库提升为Master。***在其他Slave上应用相应的差分中继日志,并从新的Master开始复制。双主+Keepalived企业在中小企业的时候,采用这种架构是最省事的。两个节点可以采用简单的单主从模式,也可以采用双主模式。而且,它们都放在同一个VLAN中。Master节点故障后,利用Keepalived/Heartbeat高可用机制快速切换到Slave节点。PXC集群PXC是基于Galera协议的MySQL高可用集群架构。Galera产品以GaleraCluster的形式为MySQL提供高可用的集群解决方案。GaleraCluster是一个集成了Galera插件的MySQL集群。GaleraReplication是Codership提供的MySQL数据同步方案,具有高可用性,易于扩展。并且可以实现多个MySQL节点之间的数据同步复制和读写,可以保证数据库服务的高可用和数据的强一致性。MGR架构MySQL在5.7.17版本正式推出GroupReplication(MySQLGroupReplication,简称MGR)。Master1、Master2、Master3,所有成员独立完成自己的事务。当客户端首次发起更新事务时,首先在本地执行事务,执行完成后,会发起事务的commit操作。在实际提交之前,需要将生成的复制写集广播并复制给其他成员。如果冲突检测成功,则该组决定事务可以提交,其他成员可以申请,否则回滚。最终,这意味着所有组成员都以相同的顺序接收相同的交易集。因此,组内成员以相同的顺序应用相同的修改,保证组内的数据强一致性。MongoDB复制情况MongoDB复制集,如下图所示:三副本架构是最基本的复制集架构,一主两备模型。主节点接受外界的读写请求,并与备节点同步数据。当主节点宕机时,自动切换到备节点,不影响线上业务,防止单点故障。MongoDB副本集自动切换,如下图:副本集的所有成员都可以接受读操作。但是,默认情况下,应用程序将其读取操作定向到主节点。一个副本集最多可以有一个Primary节点。Primary节点宕机后,集群会触发选举,选出新的Primary节点。在下面的三成员节点副本集架构中,Primary宕机后,会触发一次选举,从剩下的两个Secondary节点中选出一个新的Primary节点。MongoDB副本集读写分离设置,如下图所示:ReadPreference决定MongoDB客户端从哪个节点读取数据。默认情况下,应用程序将其读取操作定向到副本集中的主节点。指定ReadPreference选项时要小心:因为使用了异步复制,Secondary上的数据可能会因为复制延迟而不完美。默认情况下,复制集的所有读请求都会发送到Primary,Driver可以通过设置ReadPreference将读请求路由到其他节点:Primary:默认情况下,所有的读请求都会发送到Primary。PrimaryPreferred:首选Primary。如果Primary不可访问,则请求Secondary。Secondary:所有读请求都发送到Secondary。SecondaryPreferred:次要优先。当所有Secondary都不可达时,请求Primary。Nearest:读请求发送到最近的可达节点(最近的节点通过Ping检测得到)。MongoDB分片架构如下图所示:分片是一种跨多台机器分布数据的方法。MongoDB使用分片架构来帮助您管理具有非常大的数据集和高吞吐量操作的集群。大数据量、高吞吐量的业务场景,对单台服务器来说是非常具有挑战性的。例如,高查询率会耗尽服务器的CPU容量。如果workingsetsize超过了系统内存,那么压力就会压在磁盘上,这在IO上并不是我们希望看到的。MongoDB通过分片支持水平扩展。总结:MySQL复制的种类很多,集群架构选择性比较强。但是在横向扩展能力上,不如MongoDB的sharding架构强大。***,我们通过MySQL和MongoDB的不同应用场景来对这两个数据库做一个总结。从应用场景来看,正如开头介绍MySQL的特性所提到的,MySQL的使用覆盖率接近100%。从大型BAT、电商平台、游戏公司,乃至众多传统行业无不向MySQL数据库靠拢,达到逐渐垄断的趋势。MongoDB的应用也扩展到各个领域,例如游戏、物流、电子商务、内容管理、社交、物联网、视频直播等:游戏领域:使用MongoDB存储游戏用户信息,以及用户的设备、积分等直接嵌入其中,以文档的形式存储,方便查询和更新。物流场景:使用MongoDB存储订单信息,订单状态会在发货过程中不断更新,以MongoDB内嵌数组的形式存储,一次查询就可以读出订单的所有变化。社交场景:使用MongoDB存储用户信息,以及用户发布的朋友圈信息,通过地理位置索引实现附近的人和地点等功能。物联网场景:使用MongoDB存储所有连接的智能设备信息,以及设备上报的日志信息,并对这些信息进行多维分析。2009年开始接触MySQL,2012年开始接触MongoDB第一个2.1版本,对于这两个数据库,我真的是一手掌握,一手掌握。当我孤独的时候,他们总是和我在一起,感谢科技带给我们的简单快乐。无论未来如何发展,都没有所谓谁将取代谁。只是说它们各自有不同的特点,更适合我们在不同的应用场景下使用。没有宫廷勾心斗角,没有尔虞我诈,只有单纯的做技术的心,才是真正的《延禧攻略》!张苏,数据库领域的专家和名人,书籍《MySQL王者晋级之路》的作者,专家博主。近10年互联网在线处理和培训经验,专注于MySQL数据库,深入研究MongoDB、Redis等NoSQL数据库和Hadoop生态系统相关技术,具有非常丰富的理论和实践经验。【原创稿件,合作网站转载请注明原作者和出处为.com】