Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【万人收藏】Twitter工程师从0到1教你设计百万级并发应用

【万人收藏】Twitter工程师从0到1教你设计百万级并发应用

作者头像
博文视点Broadview
发布于 2024-01-15 02:21:00
发布于 2024-01-15 02:21:00
23000
代码可运行
举报
运行总次数:0
代码可运行

01

单服务器配置

万里征途总是从第一步开始的,构建一个复杂系统也是如此。我们从简单的部分着手,先让所有的功能都在一个服务器上运行。图1-1展示了如何配置单台服务器,让一切都在其上运行,包括Web应用、数据库、缓存等。

研究请求流和流量源头有助于我们理解这个配置。我们先来看请求流(如图1-2所示)。

1.用户通过输入域名(例如api.mysite.com)来访问网站。通常,域名系统(DNS)是由第三方提供的付费服务,它并不是由我们的服务器来托管的。

2.IP地址被返回给网页浏览器或者移动应用。在图1-2所示的例子中,被返回的IP地址是15.125.23.214。

3.一旦获知IP地址,HTTP请求就被直接发送给Web服务器。

4.Web服务器返回HTML页面或者JSON响应来渲染页面。

接下来,我们研究一下流量源头。Web服务器的流量有两个源头:Web应用和移动应用。

—Web应用:它运用服务器端语言(Java、Python等)来处理业务逻辑、数据存储等;它还使用客户端语言(HTML和JavaScript)来展示内容。

—移动应用:HTTP是移动应用与Web服务器之间的通信协议。而JSON(JavaScript Object Notation)因其十分简单而被广泛用作数据传输时的API响应格式。以下是一个JSON格式的API响应例子。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET /users/12 – 获取id=12的用户对象
{ 
    "id": 12,
    "firstName'": "John",
    "lastName": "Smith",
    "address":{
        "streetAddress": "21 2nd Street",
        "city": "New York",
        "state'": "NY",
        "postalCode": 10021
    },
    "phoneNumbers": [
        "212 555-1234",
        "646555-4567"
    ]
}

02

数据库

随着用户基数的增长,一台服务器已经无法满足需求,我们需要多台服务器:一台用于处理Web应用/移动应用的流量,另一台用作数据库(如图1-3所示)。把处理Web应用/移动应用流量(网络层)的服务器与数据库(数据层)服务器分开,我们就可以对它们分别进行扩展。

使用何种数据库

你可以选择传统的关系型数据库,也可以选择非关系型数据库。我们来看看它们的区别。

关系型数据库通常也叫作关系型数据库管理系统(RDBMS)或者SQL数据库,其中最流行的有MySQL、Oracle、PostgreSQL等。关系型数据库通过表和行来表示和存储数据。你可以使用SQL对不同的数据库表执行连接(join)操作。

非关系型数据库又叫作NoSQL数据库。流行的非关系型数据库有CouchDB、Neo4j、Cassandra、HBase、Amazon DynamoDB等。它们可以分为四类:键值存储、图存储、列存储和文档存储。非关系型数据库一般不支持连接操作。

对于大多数开发者而言,关系型数据库是最好的选择,因为它们已经有40多年的历史,而且一直表现不错。但如果它们无法满足你的特殊使用场景要求,你就需要考虑关系型数据库之外的选项。当需要满足如下条件时,非关系型数据库可能是一个正确的选择:

—你的应用只能接受非常低的延时。

—应用中的数据是非结构化的,或者根本没有任何关系型数据。

—只需要序列化(JSON、XML、YAML等格式)和反序列化数据。

—需要存储海量数据。

03

纵向扩展 vs. 横向扩展

纵向扩展也叫作向上扩展,指的是提升服务器的能力(CPU、RAM等)。横向扩展也叫作向外扩展,指的是为你的资源池添加更多服务器。

当流量小的时候,纵向扩展是一个很好的选择,其主要优势是简单。不过,它有一些重大局限。

—纵向扩展是有硬性限制的,你不可能给一台服务器无限添加CPU和内存。

—纵向扩展没有故障转移和冗余。一旦一台服务器宕机,网站/应用也会随着一起完全不可用。

由于纵向扩展存在这些限制,因此对于大型应用来说,采用横向扩展更合适一些。

在我们前面的设计中,用户是直接连接到Web服务器的。一旦服务器离线,用户就无法访问网站了。还有一种场景是,非常多的用户同时访问Web服务器,达到了其负载上限,这时用户就会普遍感受到网站响应慢或者无法连上服务器。解决这些问题的最佳方法是使用负载均衡器

04

负载均衡器

负载均衡器会把输入流量均匀分配到负载均衡集里的各个Web服务器上。图1-4展示了负载均衡器是怎么工作的。

如图1-4所示,用户可以直接连接该负载均衡器的公共IP地址。这样设置后,Web服务器就再也不能被任何客户端直接访问了。为了提高安全性,服务器之间的通信使用私有IP地址。私有IP地址只可以被同一个网络中的服务器访问,在公网中是无法访问的。负载均衡器和Web服务器之间使用私有IP地址来通信。

增加了负载均衡器和一台Web服务器后,我们成功解决了网络层的故障转移问题,提升了网络层的可用性。具体细节如下:

—如果服务器1离线,所有的流量都会被路由到服务器2,从而避免整个网站宕机。我们可以之后再将一台新的“健康的”Web服务器添加到服务器池中,以平衡负载。

—如果网站流量增长非常快,两台服务器不足以处理这些流量,那么负载均衡器可以轻松地解决这个问题。只需要在服务器池中添加更多服务器,负载均衡器就会自动将请求发给新加入的服务器。

现在网络层看来已经不错了,那么数据层呢?目前的设计方案中只有一个数据库,所以无法支持数据库的故障转移和冗余。数据库复制是解决这些问题的常用技巧。

05

数据库复制

根据维基百科上的定义,“在很多数据库管理系统中,通常都可以利用原始数据库(Master,主库)和拷贝数据库(Slave,从库)之间的主从关系进行数据库复制。”。

主库通常只支持写操作,从库保存主库的数据副本且仅支持读操作。所有修改数据的指令,如插入、删除或更新等,都必须发送给主库来执行。在大部分应用中,对数据库的读操作远多于写操作,因此系统中从库的数量通常多于主库的数量。图1-5展示了一个主库搭配多个从库的例子。

数据库复制有如下优点:

—性能更好。在主从模式下,所有的写操作和更新操作都发生在主节点(主库)上,而读操作被分配到各个从节点(从库),因此系统能并行处理更多的查询,性能得到提升。

—可靠性高。如果有一台数据库服务器因自然灾害而损毁,比如遭遇台风或者地震,数据依然被完好保存,你不需要担心数据会丢失,因为这些数据已经被复制到处于不同地理位置的其他数据库服务器中。

—可用性高。由于不同物理位置的从库都复制了数据,因此即使一台数据库服务器宕机,你的网站依然可以运行,因为另一台数据库服务器里存储了数据。

前面讨论了负载均衡器是如何帮助提升系统可用性的,这里我们问一个同样的问题:如果有数据库服务器宕机了怎么办?图1-5所示的架构可以应对这种情况。

—如果只有一个从库,而它宕机了,则系统暂时会将读操作路由至主库。一旦发现有从库宕机,就会有一个新的从库来替代它。要是有多个从库可用,读操作会被重定向到其他正常工作的从库上;同样,也会有一个新的数据库服务器来替代宕机的那个。

—如果主库宕机,会有一个从库被推选为新的主库。所有的数据库操作会暂时在新的主库上执行。另一个从库会替代原来的从库并立即开始复制数据。在生产环境中,因为从库的数据不一定是最新的,所以推选一个新的主库会更麻烦。缺失的数据需要通过运行数据恢复脚本来补全。尽管还有别的数据复制方式可以解决数据缺失问题,比如多主复制或者循环复制,但是它们的设置更加复杂,本书不对这些内容进行讨论。感兴趣的读者可以进一步阅读相关参考资料。

图1-6展示了添加了负载均衡器和数据库复制之后的系统设计方案。

我们再来看一下现在的设计:

—用户从DNS获取负载均衡器的IP地址。

—用户通过这个IP地址连接负载均衡器。

—HTTP请求被转发到服务器1或者服务器2上。

—Web服务器在从库中读取用户数据。

—Web服务器把所有修改数据的操作请求都转发到主库上,包括写、更新和删除操作。

现在我们对于网络层和数据层都有了一定的理解,接下来可以提升加载和响应速度了。可以通过添加缓存层、把静态资源(JavaScript、CSS、图片、视频文件)转移到内容分发网络(CDN)上来实现加速。

06

缓存

缓存是临时的存储空间,用于存储一些很耗时的响应结果或者内存中经常被访问的数据,这样后续再访问这些数据时能更快。如图1-6所示,每次加载一个新网页,都要执行一个或者多个数据库请求来获取数据。不断向数据库发送请求会使应用的性能受到很大影响,而缓存可以缓解这种情况。

缓存层

缓存层是一个临时数据存储层,比数据库快很多。设置独立缓存层的好处有:提高系统性能,减轻数据库的工作负载以及能够单独扩展缓存层。图1-7展示了一种设置缓存层的方式。

当收到一个请求时,Web服务器首先检查缓存中是否有可用的数据:如果有,Web服务器就直接将数据返回给客户端;如果没有,就去查询数据库并把返回的响应存储在缓存中,再将其返回给Web服务器。这种缓存策略叫作通过缓存读(Read-through Cache)。根据数据的类型、大小和访问模式,可以采用不同的缓存策略。在网站Codeahoy上有一篇文章“Caching Strategies and How to Choose the Right One”,解释了不同的缓存策略是如何工作的。

大部分缓存服务器都为常见的编程语言提供了API,与其进行交互很简单。下面的代码段展示了典型的Memcached API:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SECONDS= 1
cache.set('myKey', 'hi there', 3600*SECONDS)
cache.get('myKey')

使用缓存时的注意事项

使用缓存时有以下几点需要注意:

—决定什么时候应使用缓存。如果对数据的读操作很频繁,而修改却不频繁,则可考虑使用缓存。因为被缓存的数据是存储在易变的内存中的,所以缓存服务器不是持久化数据的理想位置。比如,如果缓存服务器重启,其中的所有数据就会丢失。因此,重要的数据应该保存在持久性的数据存储中。

—过期策略。执行过期策略是好的做法。一旦缓存中的数据过期,就应该将其从缓存中清除。如果不设置过期策略,缓存中的数据会一直被保存在内存中。通常建议不要把过期时间设得太短,因为这样会导致系统不得不经常从数据库重新加载数据;当然,也不要设得太长,这样会导致数据过时。

—一致性:这关系到数据存储和缓存的同步。当对数据的修改在数据存储和缓存中不是通过同一个事务来操作的时候,就会发生不一致。当跨越多个地区进行扩展时,保持数据存储和缓存之间的一致性是很有挑战性的。如果你感兴趣,可以阅读Facebook的文章“Scaling Memcache at Facebook”。

—减轻出错的影响:单缓存服务器是系统中的一个潜在单点故障(Single Point Of Failure,SPOF)(如图1-8所示)。在维基百科中,单点故障的定义如下:“单点故障是指系统中的某一部分,如果它出现故障,整个系统就不能工作”。所以,推荐的做法是在不同的数据中心部署多个缓存服务器以避免单点故障。另一个推荐的做法是为缓存超量提供一定比例的内存,这样可以在内存使用量上升时提供一定的缓冲。

驱逐策略:一旦缓存已满,任何对缓存添加条目的请求都有可能导致已有条目被删除,这叫作缓存驱逐。LRU(Least-Recently-Used,最近最少使用)是最流行的缓存驱逐策略。也可以采用其他缓存驱逐策略,比如LFU(Least Frequently Used,最不经常使用)或者FIFO(First In First Out,先进先出),以满足不同的使用场景。

07

单服务器配置

内容分发网络(Content Delivery Network,CDN)是由在地理上分散的服务器组成的网络,被用来传输静态内容。CDN中的服务器缓存了像图片、视频、CSS和JavaScript文件这一类的静态内容。

动态内容缓存是一个相对新的概念,不在本书讨论的范围内。它可以基于请求路径、查询字符串、cookie和请求头来缓存HTML页面。感兴趣的读者可以访问ASW的网站以了解更多内容。本书只讲解如何使用CDN缓存静态内容。

现在我们大致介绍一下CDN是如何工作的:当用户访问一个网站时,离用户最近的CDN服务器会返回静态资源。给人的直观感受是,离CDN服务器越远,网站加载内容就越慢。举个例子,如果CDN服务器在旧金山,那么洛杉矶的用户就比欧洲的用户更快获取网站内容。图1-9展示了CDN是如何缩短加载时间的。

图1-10展示了CDN的工作流。

1.用户A尝试通过请求图片的URL去获取image.png。这个URL的域名由CDN服务商提供。亚马逊和Akamai CDN上的图片URL大概是下面这个样子:

—https://mysite.cloudfront.net/logo.jpg

—https://mysite.akamai.com/image-manager/img/logo.jpg

2.如果CDN服务器的缓存中没有image.png,CDN服务器就会向数据源服务器请求这个文件。数据源服务器可以是Web服务器,或者线上存储,比如Amazon S3。

3.数据源服务器将image.png文件返回给CDN服务器,其中包括可选的HTTP头Time-to-Live(TTL,生存时间)。TTL描述了该图片文件应该被缓存多长时间。

4.CDN服务器缓存这个图片并将其返回给用户A。这个图片一直缓存在CDN服务器中,直到TTL到期。

5.用户B发送请求,要求获取这张图片。

6.只要TTL还没到期,CDN服务器的缓存就会返回该图片。

使用CDN时的注意事项

—花销:CDN是由第三方供应商来运营的,对数据在CDN中的进出都会收费。缓存不经常使用的内容,并不能给性能带来显著的好处,应该考虑把这些内容从CDN中移出。

—设置合理的缓存过期时间:对于时间敏感的内容,设置缓存过期时间是很重要的。这个时间不应该过长或过短。如果过长,内容会不够新。如果过短,可能导致频繁地将内容从数据源服务器重新加载至CDN。

—CDN回退:要好好考虑你的网站或应用如何应对CDN故障。如果CDN出现故障暂时无法提供服务,客户端应该有能力发现这个问题,并直接向数据源服务器请求资源。

—作废文件:以下操作均可以在文件过期之前将其从CDN中移除。

调用CDN服务商提供的API来作废CDN对象。

通过对象版本化来提供一个不同版本的对象。可以在URL中添加一个参数,比如版本号,来给一个对象添加版本。比如,在查询字符串中可以加入版本号2(image.png?v=2)。

图1-11展示了加入了CDN和缓存之后的系统设计方案。

1.静态资源(JavaScript代码、CSS文件、图片等)不再由Web服务器提供,而是从CDN中获取,以提高响应速度。

2.数据被缓存后,数据库的负载就减轻了。

08

无状态网络层

现在是时候考虑横向扩展网络层了。为此,我们需要将状态(例如,用户会话数据)从网络层中移出。一个好的做法是将会话数据存储在持久性存储(如关系型数据库或NoSQL)中。集群中的每个Web服务器都可以经由数据库访问状态数据。这就是所谓的无状态网络层。

有状态架构

有状态的和无状态的服务器是有一些关键差异的。有状态的服务器处理客户端发来的一个个请求,并记下客户端的数据(状态)。无状态的服务器则不保存状态信息。

图1-12展示了一个有状态架构。

在图1-12所示的架构中,用户A的会话数据和个人资料图片会被存储到服务器1上。为了对用户A进行身份验证,必须将HTTP请求发给服务器1。如果将请求发给其他服务器,比如服务器2,由于服务器2上没有用户A的会话数据,因此身份验证就会失败。同理,用户B的所有HTTP请求必须发给服务器2;用户C的所有请求必须发给服务器3。

现在的问题是,如何将来自同一客户端的所有请求都发给同一个服务器。大部分负载均衡器都提供的黏性会话可以解决这个问题,但是会增加成本。这种方法使得添加或者移除服务器变得更加困难,同时也使得应对服务器故障变得更具挑战性。

无状态架构

图1-13展示了一个无状态架构。

在这个无状态架构中,用户的HTTP请求可以发给任意Web服务器,然后Web服务器从共享的数据存储中拉取数据。状态数据存储在共享数据存储而非Web服务器中。无状态的系统更加简单,更健壮,也更容易扩展。

图1-14展示了加入了无状态网络层后的系统设计。

如图1-14所示,我们把会话数据从网络层中移出,放到持久化存储中保存。共享数据存储可以是关系型数据库或者NoSQL(比如,Memcached、Redis)。选择NoSQL的原因是它容易扩展。自动扩展的意思是,基于网络流量自动地增加或者减少Web服务器。将状态数据从Web服务器中移除后,就很容易实现网络层的自动扩展了。

如果你的网站发展迅速,而且吸引了非常多的国际用户,要提高可用性以及在更广的地理区域提供更好的用户体验,让网站支持多数据中心就非常关键。

09

数据中心

图1-15展示了有两个数据中心的例子。正常情况下,用户会被基于地理位置的域名服务导流到最近的数据中心,也就是说流量被分散到不同的数据中心,在图1-15中有美国东部和美国西部两个数据中心。基于地理位置的域名服务(geoDNS)是一种基于用户的地理位置将域名解析为不同IP地址的DNS服务。

如果有某个数据中心出现严重的故障,可以把所有的流量转到另一个运转正常的数据中心。在图1-16所示的例子中,数据中心2(美国西部)发生了故障,全部流量被转至数据中心1(美国东部)。

要设置多数据中心,必须先解决如下技术难题:

—流量重定向。要有能把流量引导到正确数据中心的有效工具。geoDNS可以基于用户的地理位置把流量引导到最近的数据中心。

—数据同步。不同地区的用户可以使用不同的本地数据库或者缓存。在故障转移的场景中,流量可能被转到一个数据不可用的数据中心。常用的一个策略是在多个数据中心复制数据。Netflix工程博客上的文章“Active-Active for Multi-Regional Resiliency”说明了Netflix是如何实现多数据中心异步复制的。

—测试和部署:设置多数据中心后,在不同的地点测试你的网站/应用是很重要的。而自动部署工具则对于确保所有数据中心的服务一致性至关重要。

为了进一步扩展我们的系统,我们需要解耦系统中不同的组件,这样它们就可以单独扩展了。在现实世界中,很多分布式系统用消息队列来解决这个问题。

10

消息列队

消息队列是一个持久化的组件,存储在内存中,支持异步通信。它被用作缓冲区,分配异步的请求。消息队列的基本架构很简单:输入服务(也称为生产者或发布者)创建消息,并把它们发布到消息队列中;其他服务或者服务器(也称为消费者或订阅者)与消息队列连接,并执行消息所定义的操作。这个模型如图1-17所示。

解耦使消息队列成为构建可扩展和可靠应用的首选架构。有了消息队列,当消费者无法处理消息时,生产者依然可以将消息发布到队列中;就算生产者不可用,消费者也可以从队列中读取消息。

考虑以下用例:你的应用支持修改图像,包括裁剪、锐化、模糊化等,这些任务都需要时间来完成。在图1-18中,Web服务器把图像处理的任务发布到消息队列。图像处理进程或服务(Worker)从消息队列中领取这个任务,并异步执行。生产者和消费者都可以独立地扩展。队列的规模变大以后,可以加入更多的Worker,以减少处理时间。如果队列在大部分时间中都是空的,就可以减少Worker的数量。

11

记录日志、收集指标与自动化

对于一个只有几台服务器的小网站,记录日志、收集指标和自动化只是锦上添花的实践而非必需的工作。但是当网站发展成为大企业提供服务的平台时,这些工作就是必需的了。

记录日志:监控错误日志非常重要,因为它可以帮助识别系统的错误和问题。你可以监控每个服务器的错误日志,也可以用工具把各个服务器的日志汇总到一个中心化的服务中,方便搜索和查看。

收集指标:收集不同类型的指标数据,有助于获得商业洞察力和了解系统的健康状态。

以下几个指标很有用:

—主机级别指标:CPU、内存、磁盘I/O等。

—聚合级别指标:比如整个数据库层的性能,整个缓存层的性能等。

—关键业务指标:每日活跃用户数、留存率、收益等。

自动化:当系统变得庞大且复杂时,就需要创建或者使用自动化工具来提高生产力。持续集成是一个很好的做法。在这种做法中,每次代码检入(check in)都需要通过自动化工具的审核,使团队能及时发现问题。同时,将构建、测试和部署等流程自动化,可以显著提高开发人员的生产力。

添加消息队列和各种工具

图1-19展示了更新后的系统设计,因为图书版面有限,只画了一个数据中心。

1.这个系统中包含一个消息队列,它使系统更加松散地耦合且更容易从故障中恢复。

2.它包含了记录日志、监控和收集指标的功能,以及自动化工具。

随着数据与日俱增,你的数据库过载变得越来越严重。是时候扩展数据层了。

12

数据库扩展

数据库的扩展有两种方式:纵向扩展和横向扩展。

纵向扩展

纵向扩展又叫作向上扩展,就是为已有机器增加算力(CPU、内存、硬盘等)。业界有一些非常强劲的数据库服务器。亚马逊的RDS(关系型数据库服务)可以提供拥有24 TB内存的数据库服务器。这种性能强劲的数据库服务器可以存储和处理非常多的数据。举个例子,Stack Overflow的网站在2013年每个月有超过1000万的独立用户访问,但是它只有一个主数据库。然而,纵向扩展也有一些重大缺点:

—尽管可以给数据库服务器添加更多的CPU、内存等,但是硬件的能力总是有上限的。如果网站的用户基数很大,单服务器是不够的。

—更大的单点故障风险。

—总成本很高。强劲的服务器比一般的服务器贵很多。

横向扩展

横向扩展,也叫分片,就是添加更多服务器。图1-20对比了纵向扩展和横向扩展。

数据库分片是指把大数据库拆分成更小、更容易管理的部分(这些部分叫作Shard,分片)。每个Shard共享同样的数据库Schema,但是里面的数据都是这个Shard独有的。

图1-21展示了一个做了分片的数据库。根据用户ID,用户数据被分配到其中一个数据库服务器上。每次要访问数据时,就会用一个哈希函数来找对应的Shard。在我们的例子中,以user_id(用户ID)对4求余作为哈希函数。如果余数为0,那么Shard 0就被用来存储和获取数据;如果余数为1,就用Shard 1,依此类推。

图1-22展示了做过分片的数据库中的用户表示例。

实施分片策略时,要考虑的最重要的问题是选择什么分片键(Sharding Key)。分片键(也叫作分区键,Partition Key)由一个或者多个数据列组成,用来决定将数据分到哪个Shard。在图1-22所示的例子中,user_id被用作分片键。分片键可以把数据库查询路由到正确的数据库,使你高效地检索和修改数据。在选择分片键时,最重要的标准之一是选择一个可以让数据均匀分布的键。

分片是一种不错的扩展数据库的技术,但它还远不是一个完美的解决方案。它为系统引入了复杂性和新的挑战。

重分片数据:出现如下情况时,需要对数据重新分片。第一种是因为数据快速增长,单个Shard无法存储更多的数据。第二种是因为数据的分布不均匀,有些Shard的空间可能比其他的更快耗尽。当Shard被耗尽时,就需要更新用于分片的哈希函数,然后把数据移到别的地方去。我们会在第5章介绍一致性哈希算法,它是解决这个问题的常用技术。

名人问题:也叫作热点键问题。过多访问一个特定的Shard可能造成服务器过载。想象一下,把Katy Perry、Justin Bieber和Lady Gaga的数据都放在同一个Shard里,对于社交应用而言,这个Shard会因读操作太多而不堪重负。为了解决这个问题,我们可能需要为每个名人都分配一个Shard,而且每个Shard可能还需要进一步分区。

连接和去规范化(de-normalization):一旦数据库通过分片被划分到多个服务器上,就很难跨数据库分片执行连接(join)操作了。解决这个问题的常用方法就是对数据库去规范化,把数据冗余存储到多张表中,以便查询可以在一张表中执行。

在图1-23中,我们对数据库做了分片,以支持数据流量的快速增长;同时,将有些非关系型功能迁移到NoSQL数据库中,以降低数据库的负载。High Scalability网站上有一篇文章“What the Heck are You Actually Using NoSQL for?”介绍了很多NoSQL数据库的使用案例。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-01-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 博文视点Broadview 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
扒一扒这个注解,我发现还有点意思。
然后就有小伙伴来问我:我项目里面用的是 Lombok 的 @Slf4j 这个会有影响吗?
why技术
2021/12/27
5860
扒一扒这个注解,我发现还有点意思。
流量录制与回放技术实践
本文主要介绍了流量录制与回放技术在压测场景下的应用。通过阅读本篇文章,你将了解到开源的录制工具如何与内部系统集成、如何进行二次开发以支持 Dubbo 流量录制、怎样通过 Java 类加载机制解决 jar 包版本冲突问题、以及流量录制在自动化测试场景下的应用与价值等。文章共约 1.4 万字,配图17张。本篇文章是对我个人过去一年所负责的工作的总结,里面涉及到了很多技术点,个人从中学到了很多东西,也希望这篇文章能让大家有所收获。当然个人能力有限,文中不妥之处也欢迎大家指教。具体章节安排如下:
田小波
2021/08/31
6.5K3
流量录制与回放技术实践
TypeScript超详细入门教程(上)
同学你好,我是Lison。很高兴你对TypeScript感兴趣,或许你对TypeScript了解还不多,或许还有很多疑问,比如:
全栈程序员站长
2022/11/16
4.3K0
TypeScript超详细入门教程(上)
如何将你写的框架添加cocoapod支持[转]
// 代码仓库clone 地址 git clonehttps://github.com/boyXiong/XWSwiftRefreshT.git
freesan44
2018/09/05
2.1K0
如何将你写的框架添加cocoapod支持[转]
提问的智慧( 中文阅读笔记)#
原文链接:https://github.com/FredWe/How-To-Ask-Questions-The-Smart-Way
韩旭051
2019/11/08
6000
弃文从工,从小白到蚂蚁工程师,我的 Java 成长之路
我当初做出一些重要选择,如弃理从文、弃文从工的原因。 我的校招和社招的经历,以及曾经作为求职者和面试官的一些经历和经验。 分享猪场、有赞和蚂蚁工作感受。 自己的写作经历和经验。 自己的比赛经历和经验。 自己的工作经历和经验,如如何快速熟悉新项目、如何更好地做好项目,如何更好地学习源码等。 工作之外参加的各种活动。
明明如月学长
2022/09/28
4420
弃文从工,从小白到蚂蚁工程师,我的 Java 成长之路
全方位测评|M1 这款小小芯片真的全面领跑顶配 i9 Mac 嘛?你想知道的我都告诉你...
我一直觉得一个东西好不好用,并不是由自己说了算的,也不是别人说了算的,而应该是大多数人用了之后,觉得很不错,那它就是一件好东西。今天小羽除了介绍 M1 芯片的 Mac 的一些软件使用情况,更着重的是自己的使用感受。
浅羽技术
2021/03/03
3K0
全方位测评|M1 这款小小芯片真的全面领跑顶配 i9 Mac 嘛?你想知道的我都告诉你...
spark面试题目_面试提问的问题及答案
1.Spark master使用zookeeper进行HA的,有哪些元数据保存在Zookeeper? 答:spark通过这个参数spark.deploy.zookeeper.dir指定master元数据在zookeeper中保存的位置,包括Worker,Driver和Application以及Executors。standby节点要从zk中,获得元数据信息,恢复集群运行状态,才能对外继续提供服务,作业提交资源申请等,在恢复前是不能接受请求的。另外,Master切换需要注意2点 1)在Master切换的过程中,所有的已经在运行的程序皆正常运行!因为Spark Application在运行前就已经通过Cluster Manager获得了计算资源,所以在运行时Job本身的调度和处理和Master是没有任何关系的! 2) 在Master的切换过程中唯一的影响是不能提交新的Job:一方面不能够提交新的应用程序给集群,因为只有Active Master才能接受新的程序的提交请求;另外一方面,已经运行的程序中也不能够因为Action操作触发新的Job的提交请求; 2.Spark master HA 主从切换过程不会影响集群已有的作业运行,为什么? 答:因为程序在运行之前,已经申请过资源了,driver和Executors通讯,不需要和master进行通讯的。 3.Spark on Mesos中,什么是的粗粒度分配,什么是细粒度分配,各自的优点和缺点是什么? 答:1)粗粒度:启动时就分配好资源, 程序启动,后续具体使用就使用分配好的资源,不需要再分配资源;好处:作业特别多时,资源复用率高,适合粗粒度;不好:容易资源浪费,假如一个job有1000个task,完成了999个,还有一个没完成,那么使用粗粒度,999个资源就会闲置在那里,资源浪费。2)细粒度分配:用资源的时候分配,用完了就立即回收资源,启动会麻烦一点,启动一次分配一次,会比较麻烦。 4.如何配置spark master的HA? 1)配置zookeeper 2)修改spark_env.sh文件,spark的master参数不在指定,添加如下代码到各个master节点 export SPARK_DAEMON_JAVA_OPTS=”-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=zk01:2181,zk02:2181,zk03:2181 -Dspark.deploy.zookeeper.dir=/spark” 3) 将spark_env.sh分发到各个节点 4)找到一个master节点,执行./start-all.sh,会在这里启动主master,其他的master备节点,启动master命令: ./sbin/start-master.sh 5)提交程序的时候指定master的时候要指定三台master,例如 ./spark-shell –master spark://master01:7077,master02:7077,master03:7077 5.Apache Spark有哪些常见的稳定版本,Spark1.6.0的数字分别代表什么意思? 答:常见的大的稳定版本有Spark 1.3,Spark1.6, Spark 2.0 ,Spark1.6.0的数字含义 1)第一个数字:1 major version : 代表大版本更新,一般都会有一些 api 的变化,以及大的优化或是一些结构的改变; 2)第二个数字:6 minor version : 代表小版本更新,一般会新加 api,或者是对当前的 api 就行优化,或者是其他内容的更新,比如说 WEB UI 的更新等等; 3)第三个数字:0 patch version , 代表修复当前小版本存在的一些 bug,基本不会有任何 api 的改变和功能更新;记得有一个大神曾经说过,如果要切换 spark 版本的话,最好选 patch version 非 0 的版本,因为一般类似于 1.2.0, … 1.6.0 这样的版本是属于大更新的,有可能会有一些隐藏的 bug 或是不稳定性存在,所以最好选择 1.2.1, … 1.6.1 这样的版本。 通过版本号的解释说明,可以很容易了解到,spark2.1.1的发布时是针对大版本2.1做的一些bug修改,不会新增功能,也不会新增API,会比2.1.0版本更加稳定。 6.driver的功能是什么? 答: 1)一个Spark作业运行时包括一个Driver进程,也是作业的主进程,具有main函数,并且有SparkContext的实例,是程序的人口点;2)功能:负责向集群申请资源,向master注册信息,负责了作业的调度,,负责作业的解析、生成Stage并调度Task到E
全栈程序员站长
2022/11/16
1.9K0
腾讯新闻微服务1300+接口治理实践与AI治理技术债探索
腾讯新闻经过这几年的重构、服务下线、服务合并等处理后,目前遗留了大量的历史接口。腾讯新闻对端的接口没有完善的规范,文档分散在 iwiki、腾讯文档、yapi,没有使用统一的平台进行自动化的管理。客户端、前端开发环境迫切需要 Mock 能力,只能通过本地工具进行 Mock,没有办法在远程接口进行 Mock。这些问题降低了研发效率,存在大量人工沟通成本,因此针对我们业务当中遇到的这些问题进行了治理,取得不错的成果,另外也比较深入思考了如何使用 AI 来治理技术债务,借此机会分享给大家,也希望大家的业务通过我们的经验给大家带来一些帮助和思考。
腾讯云开发者
2024/12/19
2780
腾讯新闻微服务1300+接口治理实践与AI治理技术债探索
CTFHUB刷题笔记 - wuuconix's blog
本部的阮行止学长推荐了ctf web方向的刷题顺序。这几天太废了,光顾着看JOJO了2333,已经从大乔看到了星辰远征军埃及篇了,今天打算学习学习,不让自己的良心太难受。
wuuconix
2023/03/14
9840
CTFHUB刷题笔记 - wuuconix's blog
《增长黑客》节选与笔记[通俗易懂]
这本书涉及了很多具体又贴合现实的互联网产品问题,即使你是非专业人士,也应该读一读,了解开发者是如何把你当猫耍的,以便你更好地认识一些套路,解锁,为选择手机软件或者云端应用擦亮眼睛!
全栈程序员站长
2022/08/27
7.8K0
形塑新闻:AI时代新闻业的7个变化|腾讯研究院3万字报告
时至 2024 年 10 月,生成式 AI 的热潮尚未褪去,但现实也已经与 GPT-3 刚刚发布时的那种狂热图景完全不同。人们开始更冷静地审视大模型的技术局限,更关注大模型在各种领域的实际应用与落地情况,以及由此带来的改变。
小腾资讯君
2024/11/11
4160
重构区块链
撰写这篇手册,并不简单的因为区块链是一个热门话题,更因为随着研究的深入,你会发现这是一个相当复杂的领域。关于这一话题的信息来源无外乎三个方面:技术文档和代码,商业机构的宣传,研究机构或个人的整理。但是每一种媒体都因其形式、渠道或作者而带有某种偏见。技术文档固然详细精确,但是不够通俗,视野也不够广阔;商业宣传必定带有一定的偏向性;而看似中立的研究机构和媒体也因其背后资助方或者受众市场的差异而显现出意识形态的不同。区块链领域的技术人员喜欢强调其技术领先性,但偏偏这一领域在学术界还没有一致的评判标准。区块链商业机构流行的白皮书,只有极少数既保留了技术细节,又蕴含对整个体系的理解。媒体和研究机构里则存在一种悖论,那些对区块链理解不够深,但是想象力丰富的人,率先推出了所谓的畅销书,只能让普通人初步理解一些浅层的知识,无法用来灵活运用和价值创造。只有那些深入区块链一线的研究员才会意识到,这个领域还处在高速变化期,很多东西都没有定性,出书立著为时尚早。
全栈程序员站长
2022/07/23
9.8K0
重构区块链
上帝掷骰子吗–量子物理史话
大家好,又见面了,我是你们的朋友全栈君。   上帝掷骰子吗–量子物理史话   第一章黄金时代   一   我们的故事要从1887年的德国开
全栈程序员站长
2022/06/26
7.3K0
最全面、最详细web前端面试题及答案总结
本章是HTML考点的⾮重难点,因此我们采⽤简略回答的⽅式进⾏撰写,所以不会有太多详细的解释。我们约定,每个问题后我们标记『✨ 』的为⾼频⾯试题 doctype的作⽤是什么?✨ DOCTYPE是html5标准⽹⻚声明,且必须声明在HTML⽂档的第⼀⾏。来告知浏览器的解析器⽤什么⽂档标准解析这个 ⽂档,不同的渲染模式会影响到浏览器对于 CSS 代码甚⾄ JavaScript 脚本的解析 ⽂档解析类型有: BackCompat:怪异模式,浏览器使⽤⾃⼰的怪异模式解析渲染⻚⾯。(如果没有声明DOCTYPE,默认就是这个模式) CSS1Compat:标准模式,浏览器使⽤W3C的标准解析渲染⻚⾯。 IE8还有⼀种介乎于上述两者之间的近乎标准的模式,但是基本淘汰了。
全栈程序员站长
2022/08/01
8.2K0
软件设计师复习资料「建议收藏」
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说软件设计师复习资料「建议收藏」,希望能够帮助大家进步!!!
Java架构师必看
2022/06/27
6.6K0
JavaSE 编写第一个程序
介绍 JavaSE 基础的基本语法知识,不会包含特别难以理解或更深层次的内容,通俗易懂。本人是实战派,看着大幅篇章晦涩的理论,但是没有多少实践证明的书籍就头疼;同时如果知识东一点、西一点,跳跃性太大,不成体系,也比较麻烦。
全栈程序员站长
2022/09/14
6.6K0
JavaSE 编写第一个程序
推荐阅读
相关推荐
扒一扒这个注解,我发现还有点意思。
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验