既然处于空闲状态的备机房既浪费资源又不确定可用,那么让备机房也与主机房一样日常对外提供服务不就好了吗?这样一来,机房资源被利用起来,也有了承接用户流量的实战经验,这就是“同城双活”架构。
1.13.1 存储层改造“同城双活”架构与主备机房架构类似,只不过我们需要做一些改造:将两个机房的接入层IP地址都配置到DNS。这样做的效果是两个机房都能负责一部分用户请求,形成 了“双活”的局面。
如图1-58所示,A机房与B机房组成“双活”机房,并由DNS负责决定将用户请求分流到哪个机房。从对外提供服务的角度来说,两者是对等的。此外,两个机房的服务可以通过专线实现互相访问,即“跨机房调用”。
但是这里有一个核心问题还没有解决:在主备机房架构下,备机房(即B机房)存储层的数据库是A机房的从库,从库意味着只能读数据,不可写数据,也就是B机房无法处理写请求,这样的“双活”无法达到我们的预期。
我们接着对存储层的访问做一些改造:B机房的所有写数据请求在访问存储层的数据库时,直接跨机房访问A机房对应的主库——无论是将数据写入Redis、MySQL、MongoDB还是写入其他存储系统,如图1-59所示。
...
除了要考虑机房内的各个组件,也要考虑机房自身的高可用问题。使用单机房架构搭建互联网应用后台,虽然接入层、业务服务层、存储层均具备高可用架构,但由于机房是单点,所以还是避免不了机房故障会造成整个应用无法访问的问题。可能造成机房级别故障的情况有人为破坏、自然灾害等,比如断电、火灾、机房核心交换机故障、计算机病毒等。
种种不可控因素导致的机房故障,通常会造成整个应用后台不可用,这对于大部分公司来说都难以接受。当应用的用户量级已经较为可观时,解决机房单点问题便成为工程师迫在眉睫的工作。
解决机房单点问题最简单的方案是建设主备机房:
在主机房所在的城市再建设一个备机房,整个备机房的内部完全复制主机房架构,在正常情况下仅主机房工作。
在存储层,备机房数据库被部署为主机房数据库的从库,主机房与备机房通过专线做存储层数据复制。
专线是一种特殊网线,就是为某个机构拉一条独立的专用网线,也就是建立一个独立的局域网,让用户的数据传输变得可靠、可信。专线的优点是安全性好,网络通信质量高;不过,专线价格相对较高,而且需要专业人员管理。专线被广泛应用于军事、银行等场景。
专线是主备机房数据复制的核心通道。为了 ...
消息队列(Message Queue)是分布式系统中最重要的中间件之一,在服务架构设计中被广泛使用。
1.11.1 通信模式与用途消息中间件构建了这样的通信模式:
一条消息由生产者创建,并被投递到存放消息的队列中;
消费者从队列中读取这条消息,于是生产者与消费者完成了一次通信。
这种通信模式在现实生活中很常见,典型的例子是E-mail通信:
住在北京的张三想把一个重要但不紧急的消息告诉住在上海的李四,张三给李四打电话,但是李四正在忙其他的事情而未接电话,张三为了把消息传达给李四,只能不停地拨打电话直到李四接听,这无疑浪费了张三大量的时间。于是,张三选择将消息使用E-mail的方式发送,他只需要把邮件投递到李四的收件箱中就可以去忙其他的事情了,而不用去管李四是否繁忙,E-mail系统保证只要李四空闲下来查看收件箱,就必然会收到张三的消息。对于消息中间件而言,张三和李四分别是生产者和消费者,E-mail系统就是消息队列。
消息队列的通信模式为生产者和消费者带来了便捷性,如下所述。
生产者将消息投递到消息队列中就单方面完成了消息通信,比如张三只需要发送邮件,而不用等待李四阅读邮件。
消 ...
这里我们简单介绍一下其他常见的NoSQL数据库及其适用的场景,其中部分数据库会在后续服务设计章节中正式使用时再做详细介绍。
1.10.1 文档数据库文档数据库的典型代表是MongoDB和CouchDB。文档数据库普遍采用JSON格式来存储数据,而不是采用僵硬的行和列结构,其好处是可以解决关系型数据库表结构(Schema)扩展不方便的问题,以及可以存储和读/写任何格式的数据。文档数据库与键值存储系统很类似,只不过值存储的内容是文档信息。文档数据库具有很好的可扩展性。
文档数据库适用的场景如下。
数据量大,且数据增长很快的业务场景。
数据字段定义不明确,且字段在不断变化、无法统一的场景。比如商品参数信息存储,电子设备商品参数有内存大小、电池容量等,服装商品参数有尺码、面料等。
文档数据库不适用的场景如下。
需要支持事务,文档数据库无法保证在一个事务中修改多个文档的原子性。
需要支持复杂查询,例如join语句。
1.10.2 列式数据库列式数据库的典型代表是BigTable、HBase等。关系型数据库按照行来存储数据,所以它也被称为“行式数据库”;而列式数据库按照列来存储数 ...
LSM Tree(Log-Structured Merge Tree)是一种对高并发写数据非常友好的键值存储模型,同时兼顾了查询效率。LSMTree是我们下面将要介绍的NoSQL数据库所依赖的核心数据结构,例如BigTable.、HBase、 Cassandra、TiDB 等。
1.9.1 LSM Tree 的原理LSM Tree的有效性基于一个结论:磁盘或内存的顺序读/写数据性能远高于随机读/写数据性能。这个结论不仅对传统的机械硬盘成立,对SSD硬盘同样成立。
顺序读/写和随机读/写的区别:
顺序读/写:按照文件中数据的顺序有序地进行读/写操作。例如,向某磁盘文件的尾部追加数据就是一种典型的顺序写操作。
随机读/写:它不遵循文件中数据的先后顺序进行数据的读取与写入。
LSM Tree模型的思想就是在磁盘上用顺序读/写代替了随机读/写,充分发挥磁盘的读/写性能优势。LSM Tree模型主要包括如下几个组成部分。
MemTable
Immutable MemTable
SSTable ...
Redis是现在最受欢迎的NoSQL数据库之一,是一个包含多种数据结构、支持网络访问、基于内存型存储、可选持久性的开源键值存储数据库。Redis具有如下特性。
数据被存储在内存中,性能高。
支持丰富的数据类型,包括字符串(String)、列表(List)、哈希表(Hash)、集合(Set)、有序集合(Sorted Set)等数据结构和相关数据操作。
支持分布式,包括主从模式、哨兵模式、集群模式,理论上其可以无限扩展。
基于单线程事件驱动模式实现,数据操作具有原子性。
Redis的应用场景非常广泛,例如缓存系统、计数器、限流、排行榜、社交网络等,具体的应用原理我们会在后面的章节中逐一介绍。本节还是聚焦于大型互联网公司如何应用Redis,即如何构建高性能、高可用、可扩展的Redis存储系统。
1.8.1 高可用架构1:主从模式Redis也提供了主从复制机制,所以使用Redis可以很方便地构建与MySQL类似的主从模式。一个Master与若干Slave组成主从关系,当Slave与Master首次建立连接时,Master向Slave进行全量数据复制,复制结束后,再根据Master的最新 ...
几乎所有用户请求的最终表现形式都是数据的读/写,这就意味着RPC服务需要从存储层读取数据或者向存储层写入数据。本节我们将针对最常见的几种数据库详细介绍存储层技术,首先介绍关系型数据库及其典型代表MySQL。
1.7.1 关系型数据库在百度百科中,很好地解释了关系型数据库——“关系型数据库是指采用关系模型来组织数据的数据库,其以行和列的形式存储数据,以便于用户理解。关系型数据库这一系列的行和列被称为表,一组表组成了数据库。用户通过查询来检索数据库中的数据,而查询是一个用于限定数据库中某些区域的执行代码。关系模型可以被简单理解为二维表模型,而关系型数据库就是由二维表及其之间的关系组成的一个数据组织。”
在关系型数据库中,实体、实体之间的关系均由单一的结构类型来表示,这种逻辑结构是一个二维表。这里我们举一个非常经典的例子,在一个简单的学生选课系统中,实体和实体之间的关系大致如图1-25所示。
图1-25中的实体和实体之间的关系在关系型数据库中可以用图1-26所示的二维表来表示。
关系型数据库以行和列的形式存储数据,行表示一个实体记录或者实体之间的关系记录,列表示记录的属性。这一 ...
在介绍完客户端如何接入机房后,下一步讨论机房收到客户端请求后的调度处理问题。在互联网发展的早期阶段,很多小型互联网服务的后台架构其实非常简单,几乎只有业务服务器“裸奔”在所谓的“机房”里,如图1-6所示。
从图1-6中可以看出,业务后台HTTP服务器直接绑定公网IP地址与客户端建立网络连接,DNS服务器对其域名的解析结果就是HTTP服务器的一个公网IP地址。
这种架构非常轻量、清晰,但是存在如下问题,并不适合作为互联网公司的后台工业级应用架构。
可用性低:如果某个业务服务实例宕机,那么DNS服务器将无法高效地感知到其IP地址已不可用,导致被DNS解析到此IP地址的用户请求均不可用。
可扩展性差:当业务服务需要扩容时,总需要额外配置DNS;而且受限于DNS解析的生效周期,扩容后的服务新地址难以实时生效。
安全风险高:业务服务的IP地址都是公网IP地址,这相当于后台的所有网络地址都暴露在公网环境中,存在网络安全隐患。
如何解决这些问题呢?在软件架构领域有一句很经典的话:“计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决”。
没错,我们也可以在客户端和业务服务的连接之间引 ...
DNS解析是用户访问互联网的第一步,如果这一步产生了较大的网络延迟、故障甚至是数据错误,则会严重影响用户体验。如上文所述,DNS有很多优势,但是它也存在一些问题(见1.3.1节)。业界很多互联网公司都尝试去解决这些问题,比如腾讯、字节跳动、百度等公司已经给出了较为成熟的解决方案:HTTP DNS。
1.3.1 DNS存在的问题这里介绍一下DNS存在哪些问题。
首先,域名解析需要进行递归查询,这势必会带来更高的访问延迟。在理想的情况下,DNS解析只需要几毫秒或者几十毫秒就完成了,但是在实际应用中常常有1s以上的情况出现。
其次,由于本地域名服务器是分地区、分运营商的,不同运营商实现的DNS解析策略不同。而且,由于权威域名服务器获取的是本地域名服务器的IP地址,而非客户端的IP地址,所以在定位客户端地理位置时不一定准确,最终域名解析得到的IP地址对于客户端而言可能不是距离最近、最优的访问节点。更有甚者,某些运营商为了节约资源,会直接将域名解析请求转发到其他运营商的本地域名服务器(即“域名转发”),这样做的后果就是用户得到了与其网络运营商不相符的IP地址,用户访问网络请求变慢。
最后,更重 ...
客户端启动时要做的第一件事情就是通过互联网与机房建立连接,然后用户才可以在客户端与后台服务器进行网络通信。目前在计算机网络中应用较为广泛的网络通信协议是TCP/IP,它的通信基础是IP地址,因为IP地址有如下两个主要功能。
标识设备:接入网络的设备必须有一个独一无二的IP地址,这样才能唯一标识一个网络目标。
网络寻址:将数据包从一个网络设备发送到另一个网络设备,需要携带目标网络设备的IP地址,通过TCP/IP中的IP路由寻址功能,数据包最终可以到达目标网络设备。
客户端要与机房建立连接,就需要知道机房公网IP地址(暴露在互联网中可访问的IP地址),但是IP地址通常由一串冰冷的数字组成,没有可读性,不方便记忆,于是人们又制定出另一套字符型的地址方案:域名地址。“域名”是大家都很熟悉的名词,在浏览器中输入简单易记的域名(如www.baidu.com),就可以访问到对应的网站,它的底层其实是由DNS来实现的。
1.2.1 DNS的意义DNS( Domain Name System,域名系统)是互联网中的核心服务,它维护域名与对应 IP地址的映射关系,并提供将域名翻译为 ...