mysql数据库架构_MySQL数据库之互联网常用架构方案

一、数据库架构原则

高可用

高性能

可扩展

一致性

二、常见的架构方案

方案一:主备架构,只有主库提供读写服务,备库冗余作故障转移用

d6e23c05ad39f1c24460f7a33e2e9ce8.png

jdbc:mysql://vip:3306/xxdb

高可用分析:高可用,主库挂了,keepalive(只是一种工具)会自动切换到备库。这个过程对业务层是透明的,无需修改代码或配置。

高性能分析:读写都操作主库,很容易产生瓶颈。大部分互联网应用读多写少,读会先成为瓶颈,进而影响写性能。另外,备库只是单纯的备份,资源利用率50%,这点方案二可解决。

一致性分析:读写都操作主库,不存在数据一致性问题。

扩展性分析:无法通过加从库来扩展读性能。

可落地分析:两点影响落地使用。第一,性能一般,这点可以通过建立高效的索引和引入缓存来增加读性能,进而提高性能。这也是通用的方案。第二,扩展性差,这点可以通过分库分表来扩展。

方案二:双主架构,两个主库同时提供服务,负载均衡

ea3614ebb3676ed9842b8f906a0b3077.png

jdbc:mysql://vip:3306/xxdb

高可用分析:高可用,一个主库挂了,不影响另一台主库提供服务。这个过程对业务层是透明的,无需修改代码或配置。

高性能分析:读写性能相比于方案一都得到提升,提升一倍。

一致性分析:存在数据一致性问题。请看,一致性解决方案。

扩展性分析:当然可以扩展成三主循环,但不建议(会多一层数据同步,这样同步的时间会更长)。如果非得在数据库架构层面扩展的话,扩展为方案四。

可落地分析:两点影响落地使用。第一,数据一致性问题,一致性解决方案可解决问题。第二,主键冲突问题,ID统一地由分布式ID生成服务来生成可解决问题。

方案三:主从架构,一主多从,读写分离

72cf04c5b604bd97aa897e021d2fa9da.png

jdbc:mysql://master-ip:3306/xxdb

jdbc:mysql://slave1-ip:3306/xxdb

jdbc:mysql://slave2-ip:3306/xxdb

高可用分析:主库单点,从库高可用。一旦主库挂了,写服务也就无法提供。

高性能分析:大部分互联网应用读多写少,读会先成为瓶颈,进而影响整体性能。读的性能提高了,整体性能也提高了。另外,主库可以不用索引,线上从库和线下从库也可以建立不同的索引(线上从库如果有多个还是要建立相同的索引,不然得不偿失;线下从库是平时开发人员排查线上问题时查的库,可以建更多的索引)。

一致性分析:存在数据一致性问题。请看,一致性解决方案。

扩展性分析:可以通过加从库来扩展读性能,进而提高整体性能。(带来的问题是,从库越多需要从主库拉取binlog日志的端就越多,进而影响主库的性能,并且数据同步完成的时间也会更长。建议不要分多层,且一台主库一般挂3-5台从库吧。一般配置的mysql,并发最好控制在2000/s,挂5台的话,整体基本能支撑1w+/s的并发,再加上缓存和二八定律,基本能支撑小10w/s的并发,很高了。如果还不能满足需求,那还是选择去分库吧。)

可落地分析:两点影响落地使用。第一,数据一致性问题,一致性解决方案可解决问题。第二,主库单点问题,暂时没想到很好的解决方案(这点评论里给了一种方案,可参考)。

注:思考一个问题,一台从库挂了会怎样?读写分离之读的负载均衡策略怎么容错?

方案四:双主+主从架构,看似完美的方案

586ccf9c933e36f6108aaed0f7e37cc7.png

jdbc:mysql://vip:3306/xxdb

jdbc:mysql://slave1-ip:3306/xxdb

jdbc:mysql://slave2-ip:3306/xxdb

高可用分析:高可用。

高性能分析:高性能。

一致性分析:存在数据一致性问题。请看,一致性解决方案。

扩展性分析:可以通过加从库来扩展读性能,进而提高整体性能。(带来的问题同方案二)

可落地分析:同方案二,但数据同步又多了一层,数据延迟更严重。

三、一致性解决方案

第一类:主库和从库一致性解决方案

fa95e6b344435b0b9676d533cc1acda9.png

注:图中圈出的是数据同步的地方,数据同步(MySQL主从复制,简单来说就是从库从主库拉取binlog日志,再执行一遍,想深入了解可以去查阅“MySQL主从复制原理”相关资料)是需要时间的,这个同步时间内主库和从库的数据会存在不一致的情况。如果同步过程中有读请求,那么读到的就是从库中的老数据。如下图。

78bf4eb9855ec6cb235516da28ad30cf.png

既然知道了数据不一致性产生的原因,有下面几个解决方案供参考:

直接忽略,如果业务允许延时存在,那么就不去管它。

强制读主,采用主备架构方案,或者代码指定读主库(一般不建议,这样就失去了读写分离的意义),读写都走主库。

6ce0a811e49d9b211cc835243b263405.png

选择读主,写操作时根据库+表+业务特征生成一个key放到Cache里并设置超时时间(大于等于主从数据同步时间)。读请求时,同样的方式生成key先去查Cache,再判断是否命中。若命中,则读主库,否则读从库。代价是多了一次缓存读写,基本可以忽略。

dc5b378498a7bc3333f8d25f9b60b6c8.png

数据库中间件,引入开源(mycat等)或自研的数据库中间层。个人理解,思路同选择读主。数据库中间件的成本比较高,并且还多引入了一层。d338fcf459a5578c6c577b9ef85fe38b.png

第二类:DB和缓存一致性解决方案

d6cbe8bbf3c77486a5a063563c3347d0.png

先来看一下常用的缓存使用方式:

第一步:淘汰缓存;

第二步:写入数据库;

第三步:读取缓存?返回:读取数据库;

第四步:读取数据库后写入缓存。

一般来说,并发量不是特别大的话,上面的方式就可以。但是如果是高并发量的情况下,当写入时,你淘汰了缓存,但是还没写入数据库时或者主从延时,就有一个读请求完成了,此时缓存中就会缓存旧的数据。此时可以,写库完成时,等一会(根据业务场景评估)再删除一次缓存,这样缓存旧数据的概率又低了,不过这样一来数据库的压力就会有相应的增加,并且响应时间会增加。其实,要想保证数据库和缓存严格的一致性很难,甚至要付出很高的代价。网上还个方案,就是用本地内存队列来控制读请求和写请求串行化,利弊都有,感兴趣可深入研究:高并发场景下,如何保证缓存和数据库双写的一致性。另外,思考一下是不是能用基于临时顺序节点的Zookeeper分布式锁(用两个锁,一个读锁,一个写锁,当排在写锁后面的第一个读锁被通知时,读操作完成后,批量删除后面连续的读锁,注意不要引发羊群效应 -> 主备架构时)?

注:设置缓存时,一定要加上失效时间!

四、个人的一些见解

1、架构演变

架构演变一:方案一 -> 方案一+分库分表;

架构演变二:方案一 -> 方案三 -> 方案三+分库分表

架构演变三:方案一 -> 方案二 -> 方案二+分库分表

注:方案四一般不用。

2、个人见解

加缓存和索引是通用的提升数据库性能的方式;

分库分表带来的好处是巨大的,但同样也会带来一些问题,详见MySQL数据库之互联网常用分库分表方案。

不管是主备+分库分表还是主从+读写分离+分库分表,都要考虑具体的业务场景。一般大部分的数据库架构还是采用方案一和方案一+分库分表,典型的读多写少的场景用方案三+读写分离+分库分表。另外,阿里云提供的数据库云服务也都是主备方案,要想主从+读写分离需要二次架构。

记住一句话:不考虑业务场景的架构都是耍流氓。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470072.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql数据库恢复策略_MySQL 备份和恢复策略(一)

在数据库表丢失或损坏的情况下,备份你的数据库是很重要的。如果发生系统崩溃,你肯定想能够将你的表尽可能丢失最少的数据恢复到崩溃发生时的状态。本文主要对MyISAM表做备份恢复。备份策略一:直接拷贝数据库文件(不推荐)备份策略二&#xff1…

laravel方法汇总详解

1.whereRaw() 用原生的SQL语句来查询,whereRaw(select * from user) 就和 User::all()方法是一样的效果 2.whereBetween() 查询时间格式 whereBetween(problem_date, [2016-10-05 19:00:00, 2016-10-05 20:35:10]) 这种可以查到,时间格式类似这种, 查询日…

输入输出优化

被各种变态的出题者出的数据坑到了这里/sad 1 int read() 2 { 3 int num0; char chgetchar(); 4 while(ch<0&&ch>9) chgetchar(); //过滤前面非数字字符 5 while(ch>0&&ch<9) {num*10;numch-0;chgetchar();} 6 return num…

mysql整数索引没用到_MYSQL 索引无效和索引有效的详细介绍

1、WHERE字句的查询条件里有不等于号(WHERE column!...)&#xff0c;MYSQL将无法使用索引2、类似地&#xff0c;如果WHERE字句的查询条件里使用了函数(如&#xff1a;WHERE DAY(column)...)&#xff0c;MYSQL将无法使用索引3、在JOIN操作中(需要从多个数据表提取数据时)&#x…

Qt词典搜索

Qt词典搜索 采用阿凡达数据-API数据接口及爱词霸API数据接口实现词典搜索功能&#xff0c;实例字符串搜索接口分别为&#xff1a;中文词组采用“词典”&#xff0c;中文单个字采用“中华字典”&#xff0c;英文或其他字符采用“爱词霸”&#xff1b; 对应的API接口&#xff1a;…

mysql8.0.13 rpm_Centos7 安装mysql 8.0.13(rpm)的教程详解

yum or rpm&#xff1f;yum安装方式很方便&#xff0c;但是下载mysql的时候从官网下载&#xff0c;速度较慢。rpm安装方式可以从国内镜像下载mysql的rpm包&#xff0c;比较快。rpm也适合离线安装。环境说明•操作系统&#xff1a;Centos7.4 (CentOS-7-x86_64-Minimal-1804.iso)…

如何参与一个GitHub开源项目

Github作为开源项目的著名托管地&#xff0c;可谓无人不知&#xff0c;越来越多的个人和公司纷纷加入到Github的大家族里来&#xff0c;为开源尽一份绵薄之力。对于个人来讲&#xff0c;你把自己的项目托管到Github上并不表示你参与了Github开源项目&#xff0c;只能说你开源了…

mysql数据库的多实例_MySQL数据库多实例应用实战 - 橙子柠檬's Blog

本文采用的是/data目录作为mysql多实例总的根目录&#xff0c;然后规划不同 的MySQL实例端口号来作为/data下面的二级目录&#xff0c;不同的端口号就是不同实例目录&#xff0c;以区别不同的实例&#xff0c;二级目录下包含mysql数据文件&#xff0c;配置文件以及启动文件的目…

微信企业号开发[二]——获取用户信息

注&#xff1a;文中绿色部分为摘自微信官方文档 在《微信企业号开发[一]——创建应用》介绍了如何创建应用&#xff0c;但是当用户点击应用跳转到我们设定的URL时&#xff0c;其实并没有带上用户的任何信息&#xff0c;为了获取用户信息&#xff0c;我们需要借助微信提供的OAut…

mysql全套基础知识_Mysql基础知识整理

MySQL的查询过程 (一条sql语句在MySQL中如何执行)&#xff1a;客户端请求 ---> 连接器(验证用户身份&#xff0c;给予权限) ---> 查询缓存(存在缓存则直接返回&#xff0c;不存在则执行后续操作) ---> 分析器(对SQL进行词法分析和语法分析操作) ---> 优化器(主要对…

渗透思维导图

转载于:https://www.cnblogs.com/DonAndy/p/5914747.html

mysql数据库用户的创建_mysql创建用户及数据库

登陆mysql[rootdn210120 conf]# mysql -uroot创建用户及密码mysql> grant usage on *.* to hive14localhost identified by 123456 with grant option;创建数据库mysql> create database hive14 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;赋予新用户操作新数据…

【计算机视觉】论文笔记:Ten years of pedestrian detection, what have we learned?

最近正在研究行人检测&#xff0c;学习了一篇2014年发表在ECCV上的一篇综述性的文章&#xff0c;是对行人检测过去十年的一个回顾&#xff0c;从dataset&#xff0c;main approaches的角度分析了近10年的40多篇论文提出的方法&#xff0c;发现有三种方法&#xff08;DPM变体&am…

mysql命令导入导出数据库_MYSQL命令行导入导出数据库详解

Mysql命令行导入数据库&#xff1a;1&#xff0c;将要导入的.sql文件移至bin文件下&#xff0c;这样的路径比较方便2&#xff0c;同上面导出的第1步3&#xff0c;进入MySQL&#xff1a;mysql -u 用户名 -p如我输入的命令行:mysql -u root -p (输入同样后会让你输入MySQL的密码…

02-合并frame

进入IJKMediaPlayer工程--->--->选择release--->选择6s或者其他模拟器&#xff0c;Commandb编译--->选择真机版本&#xff0c;Commandb编译&#xff0c;查看finder&#xff0c;生成真机和模拟器两个版本的frameWork--->找到这个文件----> 真机和模拟器的IJKm…

recover 没有捕获异常_defer + recover 捕获所有异常

1)说明go的异常捕获需要延迟函数defer recover实现,在函数返回前,就可以捕获到, 这样其实比java的try catch更加优雅一点&#xff1b;比如: web服务器程序崩溃前,需要做一些清理,那么就可以这样搞定&#xff1b;还可以在捕获时&#xff0c;打印一些信息,继续panic,让错误往上抛…

sqoop从mysql导入hdfs_3.使用sqoop从mysql 导入数据到hdfs

使用sqoop从mysql 导入数据到hdfs注意&#xff1a;需要将mysql的jdbc驱动包放到lib目录下在conf目录中&#xff0c;执行cp sqoop-env-template.sh sqoop-env.sh#修改 ~/.bashrc&#xff0c;增加export HADOOP_CLASSPATH/opt/hadoop-2.6.0-cdh5.13.0/lib:/$HIVE_HOME/lib/*sourc…

JAVA微信开发:[17]如何获取所有关注用户

该方法获取所有关注公共账号的微信用户的openId集合&#xff0c; 再通过openId集合既可以获取所有的用户的信息。 /** * 获取所有的关注用户 * * return */ public List<String> getAllWeiXinUser() { GetExistAccessToken getExistAccessToken GetExistAccessToken…

JS中this的四种用法

1.在一般函数方法中使用 this 指代全局对象 function test(){this.x 1;alert(this.x);}test(); // 12.作为对象方法调用&#xff0c;this 指代上级对象 function test(){alert(this.x); } var o {}; o.x 1; o.m test; o.m(); // 1 3.作为构造函数调用&#xff0c;this 指代…

mysql lib 5.5.28_mysql5.5.28在Linux下的安装

mysql5.5.28在Linux下的安装1. 下载mysql2. 解压假如tar包在/home/zdw/software目录下#tar -xvf mysql-5.5.28-linux2.6-i686.tar.gz3. 移动到/usr/local/mysql#mv mysql-5.5.28-linux2.6-i686 /usr/local/添加快捷方式mysql指向mysql-5.5.28-linux2.6-i686#ln -s mysql-5.5.28…