首页 文章 精选 留言 我的

精选列表

搜索[大型语言模型],共10000篇文章
优秀的个人博客,低调大师

mysql 在大型应用中的架构演变

文正整理自:http://www.csdn.net/article/2014-06-10/2820160 可扩展性 架构的可扩展性往往和并发是息息相关,没有并发的增长,也就没有必要做高可扩展性的架构,这里对可扩展性进行简单介绍一下,常用的扩展手段有以下两种: Scale-up:纵向扩展,通过替换为更好的机器和资源来实现伸缩,提升服务能力 Scale-out:横向扩展, 通过加节点(机器)来实现伸缩,提升服务能力 对于互联网的高并发应用来说,无疑横向扩展才是出路,同时通过纵向购买更高端的机器也一直是我们所避讳的问题,也不是长久之计。那么,在横向扩展的理论下,可扩展性的理想状态是什么? 可扩展性的理想状态 一个服务,当面临更高的并发的时候,能够通过简单增加机器来提升服务支撑的并发度,且增加机器过程中对线上服务无影响(no down time),这就是可扩展性的理想状态! 架构的演变 V1.0 简单网站架构 一个简单的小型网站或者应用背后的架构可以非常简单,数据存储只需要一个Mysql Instance就能满足数据读取和写入需求(这里忽略掉了数据备份的实例),处于这个时间段的网站,一般会把所有的信息存到一个Database Instance里面。 在这样的架构下,我们来看看数据存储的瓶颈是什么? 数据量的总大小 一个机器放不下 数据的索引(B+ Tree)一个机器的内存放不下 访问量(读写混合)一个实例不能承受 只有当以上3件事情任何一件或多件满足时,我们才需要考虑往下一级演变。 从此我们可以看出,事实上对于很多小公司小应用,这种架构已经足够满足他们的需求了,初期数据量准确评估是杜绝过度设计很重要的一环,毕竟没有人愿意为不可能发生的事情而浪费自己的精力。 这里简单举个我的例子,对于用户信息这类表 (3个索引),16G内存能放下,大概2000万行数据的索引,简单的读和写混合访问量3000/s左右没有问题,你的应用场景是否? V2.0 垂直拆分 一般当V1.0 遇到瓶颈时,首先最简便的拆分方法就是垂直拆分,何谓垂直?就是从业务角度来看,将关联性不强的数据拆分到不同的Instance上,从而达到消除瓶颈的目标。以图中的为例,将用户信息数据,和业务数据拆分到不同的三个实例上。对于重复读类型比较多的场景,我们还可以加一层Cache,来减少对DB的压力。 在这样的架构下,我们来看看数据存储的瓶颈是什么? 单实例单业务依然存在V1.0所述瓶颈:遇到瓶颈时可以考虑往本文更高V版本升级,若是读请求导致达到性能瓶颈可以考虑往V3.0升级, 其他瓶颈考虑往V4.0升级。 V3.0 主从架构 此类架构主要解决V2.0架构下的读问题,通过给Instance挂数据实时备份的思路来迁移读取的压力,在MySQL的场景下就是通过主从结构,主库抗写压力,通过从库来分担读压力,对于写少读多的应用,V3.0主从架构完全能够胜任。 在这样的架构下,我们来看看数据存储的瓶颈是什么?很明了,写入量主库不能承受。 V4.0 水平拆分 对于V2.0、V3.0方案遇到瓶颈时,都可以通过水平拆分来解决,水平拆分和垂直拆分有较大区别,垂直拆分拆完的结果,在一个实例上是拥有全量数据的,而水平拆分之后,任何实例都只有全量的1/n的数据,以下图UserInfo的拆分为例,将UserInfo拆分为3个Cluster,每个Cluster持有总量的1/3数据,3个Cluster数据的总和等于一份完整数据。 注:这里不再叫单个实例 而是叫一个Cluster 代表包含主从的一个小MySQL集群。 那么,这样架构中的数据该如何路由? 1. Range拆分 sharding key按连续区间段路由,一般用在有严格自增ID需求的场景上,如UserId、UserId Range的小例子,以UserId 3000万为Range进行拆分:1号Cluster的UserId是1-3000万,2号Cluster UserId是 3001万-6000万。 2. List拆分 List拆分与Range拆分思路一样,都是通过给不同的sharding key来路由到不同的Cluster,但是具体方法有些不同。List主要用来做sharding key不是连续区间的序列落到一个Cluster的情况,如以下场景: 假定有20个音像店,分布在4个有经销权的地区,如下表所示: 地区 商店ID 号 北区 3, 5, 6, 9, 17 东区 1, 2, 10, 11, 19, 20 西区 4, 12, 13, 14, 18 中心区 7, 8, 15, 16 业务希望能够把一个地区的所有数据组织到一起来搜索,这种场景List拆分可以轻松搞定 3. Hash拆分 通过对sharding key 进行哈希的方式来进行拆分,常用的哈希方法有除余,字符串哈希等等,除余如按UserId%n的值来决定数据读写哪个Cluster,其他哈希类算法这里就不细展开讲了。 4. 数据拆分后引入的问题 数据水平拆分引入的问题主要是只能通过sharding key来读写操作,例如以UserId为sharding key的切分例子,读UserId的详细信息时,一定需要先知道UserId,这样才能推算出在哪个Cluster进而进行查询,假设我需要按UserName进行检索用户信息,需要引入额外的反向索引机制(类似HBase二级索引),如在Redis上存储username->userid的映射,以UserName查询的例子变成了先通过查询username->userid,再通过userid查询相应的信息。 实际上这个做法很简单,但是我们不要忽略了一个额外的隐患,那就是数据不一致的隐患。存储在Redis里的username->userid和存储在MySQL里的userid->username必须需要是一致的,这个保证起来很多时候是一件比较困难的事情,举个例子来说,对于修改用户名这个场景,你需要同时修改Redis和Mysql。这两个东西是很难做到事务保证的,如MySQL操作成功,但是Redis却操作失败了(分布式事务引入成本较高)。对于互联网应用来说,可用性是最重要的,一致性是其次,所以能够容忍小量的不一致出现. 毕竟从占比来说,这类的不一致的比例可以微乎其微到忽略不计。(一般写更新也会采用mq来保证直到成功为止才停止重试操作) 在这样的架构下,我们来看看数据存储的瓶颈是什么? 在这个拆分理念上搭建起来的架构,理论上不存在瓶颈(sharding key能确保各Cluster流量相对均衡的前提下)。不过确有一件恶心的事情,那就是Cluster扩容的时候重做数据的成本,如我原来有3个Cluster,但是现在我的数据增长比较快,我需要6个Cluster,那么我们需要将每个Cluster 一拆为二,一般的做法是: 摘下一个slave,停同步 对写记录增量log(实现上可以业务方对写操作多一次写持久化mq或者MySQL主创建trigger记录写等等方式) 开始对静态slave做数据一拆为二 回放增量写入,直到追上的所有增量,与原Cluster基本保持同步 写入切换,由原3 Cluster 切换为6 Cluster 有没有类似飞机空中加油的感觉,这是一个脏活,累活,容易出问题的活,为了避免这个,我们一般在最开始的时候,设计足够多的sharding cluster来防止可能的Cluster扩容这件事情。 V5.0 云计算 腾飞(云数据库) 云计算现在是各大IT公司内部作为节约成本的一个突破口,对于数据存储的MySQL来说,如何让其成为一个SaaS是关键点。在MS的官方文档中,把构建一个足够成熟的SaaS(MS简单列出了SAAS应用的4级成熟度)所面临的3个主要挑战:可配置性,可扩展性,多用户存储结构设计称为"three headed monster"。可配置性和多用户存储结构设计在MySQL SaaS这个问题中并不是特别难办的一件事情,所以这里重点说一下可扩展性。 MySQL作为一个SaaS服务,在架构演变为V4.0之后,依赖良好的sharding key设计,已经不再存在扩展性问题,只是他在面对扩容缩容时,有一些脏活需要干,而作为SaaS,并不能避免扩容缩容这个问题,所以只要能把V4.0的脏活变成:第1,扩容缩容对前端APP透明(业务代码不需要任何改动);第2,扩容缩容全自动化且对在线服务无影响。如果实现了这两点,那么他就拿到了作为SaaS的门票。 对于架构实现的关键点,需要满足对业务透明,扩容缩容对业务不需要任何改动,那么就必须eat our own dog food,在你MySQL SaaS内部解决这个问题,一般的做法是我们需要引入一个Proxy,Proxy来解析SQL协议,按sharding key来寻找Cluster,判断是读操作还是写操作来请求Master或者Slave,这一切内部的细节都由Proxy来屏蔽。 对于架构实现的关键点,扩容缩容全自动化且对在线服务无影响; 扩容缩容对应到的数据操作即为数据拆分和数据合并,要做到完全自动化有非常多不同的实现方式,总体思路和V4.0介绍的瓶颈部分有关,目前来看这个问题比较好的方案就是实现一个伪装Slave的Sync Slave,解析MySQL同步协议,然后实现数据拆分逻辑,把全量数据进行拆分。具体架构见下图: 其中Sync Slave对于Original Master来说,和一个普通的Mysql Slave没有任何区别,也不需要任何额外的区分对待。需要扩容/缩容时,挂上一个Sync slave,开始全量同步+增量同步,等待一段时间追数据。以扩容为例,若扩容后的服务和扩容前数据已经基本同步了,这时候如何做到切换对业务无影响? 其实关键点还是在引入的Proxy,这个问题转换为了如何让Proxy做热切换后端的问题。这已经变成一个非常好处理的问题了。 另外值得关注的是:2014年5月28日——为了满足当下对Web及云应用需求,甲骨文宣布推出MySQL Fabric,在对应的资料部分我也放了很多Fabric的资料,有兴趣的可以看看,说不定会是以后的一个解决云数据库扩容缩容的手段。 V more ? 等待革命…… 淘宝用例 淘宝RDS 云数据库设计:http://blog.csdn.net/ywh147/article/details/8954625http://www.infoq.com/cn/news/2012/10/taobao-ump Mysql Fabric http://mysqlmusings.blogspot.jp/2013/09/brief-introduction-to-mysql-fabric.html http://vnwrites.blogspot.jp/2013/09/mysqlfabric-sharding-introduction.html http://vnwrites.blogspot.in/2013/09/mysqlfabric-sharding-example.html http://vnwrites.blogspot.in/2013/09/mysqlfabric-sharding-migration.html http://vnwrites.blogspot.jp/2013/09/mysqlfabric-sharding-maintenance.html 本文转自 张冲andy 博客园博客,原文链接:http://www.cnblogs.com/andy6/p/5789252.html ,如需转载请自行联系原作者

优秀的个人博客,低调大师

基于Java技术的大型网站架构方案

Web层 主体架构可以基于 Struts 1.X/2.X,当然有很多更好的控制层框架供选择,以快速敏捷为准则吧。 抽象出核心库封装 控制器和中间层 的操作。 在大规模集群环境下,session复制会引起严重的性能问题。考虑用 集群缓存 + cookie验证 代替session实现权限控制吧。 Cache层 配置 Memcache 组成集群缓存 对 Memcache 客户端进行封装 Memcached 节点组成池,调用示意:opList (BizName, 策略 ...) 中间层 “中间层”可以理解为基于应用和数据之间的层次。它被设计用来为Web应用提供:数据缓存 和 对应用透明的数据访问——即应用不需要考虑数据表拆分的问题。以服务的方式提供对存储层的高性能调用以及分布式计算。可供选择的框架: ICE Hadoop 直接基于Memcache开发(减少复杂度,推荐) 存储 推荐MySQL,理由:免费,经过实践检验,有大量成熟的案例、解决方案、技术支持。 小规模:一个 data table 维护存储服务器阵列,内容 -> mount …… 大规模:Master-Slave模式+MySQL Proxy,实现数据库读写分离。在中间层的包装下,可做如下扩展,以支持更大规模的数据存取: 数据库/表水平拆分,例 User -> User33% + User33% + User34% 数据库/表垂直拆分,例 User -> UserBaseInfo + UserAddrInfo 也可考虑使用 LongStore (龙存) 解决方案,由龙存管理存储阵列…… 部署 划分子域名,每个子域名一个Web应用包,互不干扰 静态资源(css, js, image ...)使用专门的静态服务器 负载均衡 小规模:DNS轮询。 大规模:F5, 2*X 台F5服务器,F5是L4/L7层交换机,每台至少可处理200万连接(与服务器内存有关)。 Ngnix是L7层交换,LVS负载均衡也是一种方案 Web中间件选择 Tomcat - 最高400并发 Apache - 最高2000并发 Ngnix - 优于Apache 采用方案:Ngnix + Resin ,理由: Resin提供更为快速的servlet引擎 - 选择Resin。 gzip问题 - Resin在单独处理gzip时存在内存溢出的隐患,因此要加一层 Ngnix。 Ngnix 能减少单独使用Resin时的内存占用 - Resin建立1000个连接使用1000个线程;加Ngnix后,透过其“异步连接”、“建立长连接”机制使Resin内存压力大大减小。 Ngnix 针对Linux系统有性能优化措施 - 0 Copy, send file ... 因此采用:1 Ngnix + 1 Resin,一对一。 静态服务器采用:Squid + Apache, why? because Squid has cache ability ... 新变化 - Nginx从0.7.48版本开始,支持了类似Squid的缓存功能。这个缓存是把URL及相关组合当作Key,用md5编码哈希后保存在硬盘上,所以它可以支持任意URL链接,同时也支持 404/301/302 这样的非200状态码。虽然目前官方的Nginx Web缓存服务只能为指定URL或状态码设置过期时间,不支持类似Squid的PURGE指令,手动清除指定缓存页面,但是,通过一个第三方的Nginx模块,可以清除指定URL的缓存。 Nginx的Web缓存服务主要由proxy_cache相关指令集和fastcgi_cache相关指令集构成,前者用于反向代理时,对后端内容源服务器进行缓存,后者主要用于对FastCGI的动态程序进行缓存。两者的功能基本上一样。 最新的Nginx 0.8.31版本,proxy_cache和fastcgi_cache已经比较完善,加上第三方的ngx_cache_purge模块(用于清除指定URL的缓存),已经可以完全取代Squid。有的网站已经在生产环境使用了 Nginx 的 proxy_cache 缓存功能超过两个月,十分稳定,速度不逊于 Squid。 在功能上,Nginx已经具备Squid所拥有的Web缓存加速功能、清除指定URL缓存的功能。而在性能上,Nginx对多核CPU的利用,胜过Squid不少。另外,在反向代理、负载均衡、健康检查、后端服务器故障转移、Rewrite重写、易用性上,Nginx也比Squid强大得多。这使得一台Nginx可以同时作为"负载均衡服务器"与"Web缓存服务器"来使用。以下是配置片段供参考: view plaincopy to clipboardprint? http { ... client_body_buffer_size 512k; proxy_connect_timeout 5; proxy_read_timeout 60; proxy_send_timeout 5; proxy_buffer_size 16k; proxy_buffers 4 64k; proxy_busy_buffers_size 128k; proxy_temp_file_write_size 128k; ... #注:proxy_temp_path和proxy_cache_path指定的路径必须在同一分区 proxy_temp_path /data0/proxy_temp_dir; #设置Web缓存区名称为cache_one,内存缓存空间大小为200MB,1天清理一次缓存,硬盘缓存空间大小为30GB。 proxy_cache_path /data0/proxy_cache_dir levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g; } server { ... location / { #如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。 proxy_next_upstream http_502 http_504 error timeout invalid_header; proxy_cache cache_one; #对不同的HTTP状态码设置不同的缓存时间 proxy_cache_valid 200 304 12h; proxy_cache_valid 301 302 1h; #以域名、URI、参数组合成Web缓存的Key值,Nginx根据Key值哈希,存储缓存内容到二级缓存目录内 proxy_cache_key $host$uri$is_args$args; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_pass http://backend_server; expires 1d; } #用于清除缓存,假设一个URL为 http://192.168.1.44/test.txt,通过访问 http://192.168.4.44/purge/test.txt就可以清除该URL的缓存。 location ~ /purge(/.*) { #设置只允许指定的IP或IP段才可以清除URL缓存。 allow 127.0.0.1; allow 192.168.0.0/16; deny all; proxy_cache_purge cache_one $host$1$is_args$args; } #扩展名以.php、.jsp、.cgi结尾的动态应用程序不缓存。 location ~ .*\.(php|jsp|cgi)?$ { proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_pass http://backend_server; } } http { ... client_body_buffer_size 512k; proxy_connect_timeout 5; proxy_read_timeout 60; proxy_send_timeout 5; proxy_buffer_size 16k; proxy_buffers 4 64k; proxy_busy_buffers_size 128k; proxy_temp_file_write_size 128k; ... #注:proxy_temp_path和proxy_cache_path指定的路径必须在同一分区 proxy_temp_path /data0/proxy_temp_dir; #设置Web缓存区名称为cache_one,内存缓存空间大小为200MB,1天清理一次缓存,硬盘缓存空间大小为30GB。 proxy_cache_path /data0/proxy_cache_dir levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g; } server { ... location / { #如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。 proxy_next_upstream http_502 http_504 error timeout invalid_header; proxy_cache cache_one; #对不同的HTTP状态码设置不同的缓存时间 proxy_cache_valid 200 304 12h; proxy_cache_valid 301 302 1h; #以域名、URI、参数组合成Web缓存的Key值,Nginx根据Key值哈希,存储缓存内容到二级缓存目录内 proxy_cache_key $host$uri$is_args$args; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_pass http://backend_server; expires 1d; } #用于清除缓存,假设一个URL为 http://192.168.1.44/test.txt,通过访问 http://192.168.4.44/purge/test.txt就可以清除该URL的缓存。 location ~ /purge(/.*) { #设置只允许指定的IP或IP段才可以清除URL缓存。 allow 127.0.0.1; allow 192.168.0.0/16; deny all; proxy_cache_purge cache_one $host$1$is_args$args; } #扩展名以.php、.jsp、.cgi结尾的动态应用程序不缓存。 location ~ .*\.(php|jsp|cgi)?$ { proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_pass http://backend_server; } } 同时,对于影响页面展现的静态资源,例如:css, js 等可以放在具有优质带宽的IDC(IDC=互联网数据中心,优质/高速的带宽也比较贵,正所谓一份价钱一分货);其他的静态资源,如图片等可以放在价格相对低廉的IDC中,以域名区分两种静态资源,节省每一分钱。 网络拓扑图 / Ngnix - 1:1 - Resin F5 -- \ Squid - 1:n - Apache 监控统计平台 业务统计 - 用户访问统计 软件性能 - 应用系统监控,例如:请求响应时间…… 硬件/网络性能 - Ganglia监控 其它要点 IE浏览器对同一域名(包括子域名)只能建立2个连接,连接多了只能排队…… 双F5架构,两台职能划分不同,镜像,心跳接管…… Raid存储阵列…… Linux操作系统及其优化…… 本文转自胡奇 51CTO博客,原文链接:http://blog.51cto.com/huqicto/280669,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册