vs 输入代码时出现火花_vscode 火花_火花监控如何每天处理10B请求

vscode 火花_火花监控如何每天处理10B请求

vscode 火花_火花监控:如何每天处理10B请求

vscode 火花

Taboola的Spark监视架构可处理每日10B +的用户事件

他们说独角兽不存在,但您当然知道那是不对的 -至少在科技界并非如此 。 当我们希望了解有关Spark监视的更多信息时,我们的首选是这些独角兽之一-Taboola 。 这篇文章将深入了解他们如何为5.5亿唯一身份每月用户提供服务,以及如何使用Spark提供2000亿每月的内容推荐。 以这种规模工作意味着错误很小,只有0.1%的时间会发生,很容易影响成千上万的用户。 那么您如何应对这种压力? 您需要遵循哪些指标? 您需要掌握哪些工具? 感谢Taboola的研发总监Tal Sliwowicz为我们提供了他的集群的内部视图,以回答这些问题。

新帖:火花监控:如何处理每天的10B请求http://t.co/KtnxOKzhAe pic.twitter.com/6zREeY9aZ9

— Takipi(@takipid) 2015年6月2日

Taboola中的数字

塔博拉烟囱

Taboola从0.7版开始就使用Spark,目前在带有40个活动节点的1.2版上运行其Spark集群。 一个节点具有256GB RAM和8T SSD,其中Cassandra用作Spark上的读/写操作的主要数据源,并带有MySQL提示。 此设置在Taboola的私有数据中心中运行,并由Mesos和Zookeeper进行管理。

为了进行监视,它们遵循的度量标准通过Graphite推送-其中包括有关硬件,JVM的数据,以及更具体的代码级数据以及它们遵循的计数器和自定义统计信息。 数据在Grafana中可视化,最重要的是, Nagios和Icinga设置了警报系统。 要获得Graphite的更多动手知识,您可以查看此逐步指南, 为您的应用选择正确的Graphite体系结构 。 在日志记录方面,Taboola使用ELK堆栈搜索和可视化其日志。

如何收集数据?

除了向Spark的Web UI报告的标准指标外,Tabola在机器上还具有独立的Sensu代理,用于对Graphite报告的硬件监视。 对于代码级指标,正在使用Dropwizard的指标库。 除此之外,JMX Bean与Jolokia一起使用和收集,使这些Bean可用于查询。 从一开始就在Taboola中使用了此Spark监视设置,请记住,没有监视的大型系统会失去其大部分价值。 最初,所有监视都基于提取数据,但是现在添加了另一层,以使用RabbitMQ管理此数据流。

您可以预期的错误类型

Spark 1.2在基础架构方面非常稳定,您可能会遇到的问题主要是因为您做错了事,而不是因为Spark行为不当。 让我们看一下您在生产中可能遇到的事件类型以及它们需要执行哪些操作(这些操作大致分为硬件和应用程序特定的问题):

1.应用逻辑

Spark是为处理数据而设计的,因此您在应用程序级别上会遇到的最常见问题是关于您拥有的数据的某些假设不正确。 并不是说生产中没有错误-而是某种异国情调和特定于应用程序的错误。 意思是,一些自定义指标超出了您对其统计模型有一些假设的阈值。 如果这些假设不适用–可能意味着出了点问题。 此外,您还经常会偶尔看到一些例外情况,例如,尝试加载一些您认为存在但不是由于Cassandra问题引起的数据。

测量–自定义指标和阈值的重要性

假设您要测量每秒处理多少个事件,或者应该忽略多少个事件,这可以通过使用指标和Jolokia来实现。 Taboola还使用火花累加器报告这些指标。 另一个重要的指标来自检查何时将新数据成功写入Cassandra的时间。 您将获得一个时间戳,如果时间戳超过某个阈值,即未写入任何数据,则表示例如经过一分钟而未写入数据,则可能会出现问题。

采取警报阈值

当其中某些情况发生并且警报触发时,首先要去的地方是Spark Web UI。 很多时候,它可以很好地指示出什么地方出了问题。 您可以看到问题所在,获取执行程序的线程转储,并查看它们的挂起位置。 如果某些任务失败,则可以查看引发了哪些异常,并在日志中或使用Takipi继续搜索其原因。 基本上,它使您可以查看问题发生在哪个节点以及异常消息-这样您便拥有了日志挖掘所需的信息。

如果您使用的是ELK堆栈,则第二个地方是Kibana,然后查看要到达那里的数据类型。

例如,在Taboola中,他们具有更新堆栈MySQL部分的过程。 因此,他们在更新过程中遇到了一个问题,即在设置的自定义警报发现问题之前,需要从数据库本身获取有关该问题的指示。 这是有可能的,这要归功于他们监视的自定义指标,该指标遵循上一次成功写入数据库的时间。 它超过了他们设置的阈值,然后他们从Spark Web UI中获取了一个线程转储,这使他们能够找到问题的原因并解决问题。

2.硬件问题

在硬件方面,到目前为止,Taboola已经成功进行了对称部署,并且具有相同数量的Spark和Cassandra实例。 这里要注意的动作是添加更多节点。 由于Cassandra和Spark可以很好地进行扩展。 通常这是增加更多CPU能力的问题,这就是他们对其进行监视的原因。

您怎么知道您需要添加一个额外的节点?

Taboola的流量在增加,并且他们定期获取越来越多的数据以供处理。 数据保存在Cassandra中,然后经过一段时间,然后将其删除,但是当他们注意到磁盘空间利用率的步伐逐渐提高时,他们将添加另一个节点并向其中传递一些数据。 当磁盘利用率超过某个阈值(例如50%)时,将触发触发添加新节点的警报。 由于整个过程都受到监控-这不足为奇。

在CPU方面,如果由于流量增加或某些逻辑更改而导致处理活动更多,从而使它们运行的??处理量比平常多-他们看到CPU利用率超过某个阈值,因此添加了另一个Spark节点。

3.缺少的链接–无需远程调试即可获取变量数据

塔尔认为,塔博拉目前的主要痛点是对错误的更深入分析。 他说:“即使在获得堆栈跟踪之后,也无法将我们引导到导致每个错误的真正根本原因和可变状态。 这是痛苦的失踪”。 在使用Takipi监视Taboola的生产环境以解决此问题并查看导致每个错误的变量值之后,Tal说,下一步就是将其安装在其Spark节点上。 “目前,只有在意识到出了点问题并尝试重新创建问题后,我们才能使用远程调试器手动连接JVM,以便我们找出导致问题的状态。 这非常麻烦,并且不允许我们查看事件的历史记录并完全了解可能出了问题的地方。”

结论

即使您的代码经过了彻底的测试,也不意味着您不会在生产系统中遇到问题,这绝对是监视关键指标以了解如何前进的绝对必要。 需要一种全方位的监视策略,以便能够对可能发生的任何事件做出及时的响应,并且不给意外带来任何余地。

我们还要感谢Tal Sliwowicz ,他分享了他在Taboola的Spark基础架构扩展方面的见解和经验。 如果您还有其他有关Tal的Spark监控相关问题,请使用下面的评论部分。

翻译自: https://www.javacodegeeks.com/2015/06/spark-monitoring-how-to-handle-10b-requests-a-day.html

vscode 火花

vscode 火花_火花监控如何每天处理10B请求相关教程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个8b10b解码器的Verilog实现代码,非查表代码: ```verilog module Decoder_8b10b( input clk, rst_n, input [9:0] data_in, output reg [7:0] data_out, output reg [1:0] code_err ); // Internal signals reg [7:0] data_reg; reg [4:0] disp_cnt; reg [1:0] comma_cnt; reg [1:0] code_err_reg; // Constants parameter K28_5 = 10'b0011110101; parameter K28_6 = 10'b0100001010; parameter K28_7 = 10'b0100010101; parameter K28_4 = 10'b0011101010; parameter K28_1 = 10'b0001110100; parameter K28_2 = 10'b0010001011; parameter K28_3 = 10'b0010010100; parameter K28_0 = 10'b0001101011; parameter K23_7 = 8'b11110101; parameter K23_6 = 8'b11101010; parameter K23_5 = 8'b11010101; parameter K23_4 = 8'b10101010; parameter K23_3 = 8'b01110101; parameter K23_2 = 8'b01101010; parameter K23_1 = 8'b01010101; parameter K23_0 = 8'b00101010; // State machine states parameter IDLE = 2'b00; parameter DISP = 2'b01; parameter COMMA = 2'b10; // State machine reg [1:0] state; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin state <= IDLE; data_reg <= 8'h00; disp_cnt <= 5'h00; comma_cnt <= 2'h00; code_err_reg <= 2'h00; end else begin case (state) IDLE: begin if (data_in == K28_5 || data_in == K28_6 || data_in == K28_7 || data_in == K28_4 || data_in == K28_1 || data_in == K28_2 || data_in == K28_3 || data_in == K28_0) begin state <= DISP; data_reg <= 8'h00; disp_cnt <= 5'h00; code_err_reg <= 2'h00; end else if (data_in == K23_7 || data_in == K23_6 || data_in == K23_5 || data_in == K23_4 || data_in == K23_3 || data_in == K23_2 || data_in == K23_1 || data_in == K23_0) begin state <= COMMA; data_reg <= 8'h00; comma_cnt <= 2'h00; code_err_reg <= 2'h00; end else begin data_out <= 8'h00; code_err <= 2'h01; end end DISP: begin if (disp_cnt < 5'h0A) begin disp_cnt <= disp_cnt + 1; end else begin state <= IDLE; data_out <= data_reg; code_err <= code_err_reg; end end COMMA: begin if (comma_cnt < 2'h02) begin comma_cnt <= comma_cnt + 1; end else begin state <= IDLE; data_out <= data_reg; code_err <= code_err_reg; end end endcase end end // Data register update always @(posedge clk or negedge rst_n) begin if (!rst_n) begin data_reg <= 8'h00; end else if (state == DISP) begin data_reg[6:0] <= {data_in[9:8], data_in[6:5], data_in[3:0]}; data_reg[7] <= ~(data_in[7] ^ data_in[4] ^ data_in[2] ^ data_in[0]); code_err_reg <= 2'h00; case (data_in) K28_5, K28_6, K28_7, K28_4: begin if (data_in[9:8] == 2'b01 || data_in[9:8] == 2'b10) begin code_err_reg <= 2'h02; end end K28_1, K28_2, K28_3, K28_0: begin if (data_in[9:8] == 2'b00 || data_in[9:8] == 2'b11) begin code_err_reg <= 2'h02; end if (~data_in[9] & ~data_in[8] & data_in[7:4] == 4'b1000) begin code_err_reg <= 2'h02; end end endcase end else if (state == COMMA) begin data_reg <= {data_in[9:4], data_in[3:0]}; code_err_reg <= 2'h00; case (data_in) K23_7, K23_6, K23_5, K23_4, K23_3, K23_2, K23_1, K23_0: begin if (data_in == K23_7 || data_in == K23_6 || data_in == K23_5 || data_in == K23_4) begin if (~data_in[7] & ~data_in[6] & data_in[5:2] == 4'b1000) begin code_err_reg <= 2'h02; end end else if (data_in == K23_3 || data_in == K23_2 || data_in == K23_1 || data_in == K23_0) begin if (~data_in[1] & ~data_in[0] & data_in[7:4] == 4'b1000) begin code_err_reg <= 2'h02; end end end endcase end end endmodule ``` 该解码器接收一个10位输入信号 `data_in`,并输出一个8位解码信号 `data_out` 和一个2位错误码 `code_err`。该解码器使用一个状态机来解码输入信号,并使用一个数据寄存器 `data_reg` 来存储当前解码的数据。在 `IDLE` 状态下,如果输入信号匹配任何一个8b/10b编码,则进入 `DISP` 状态或 `COMMA` 状态来解码数据或逗号。在 `DISP` 状态下,解码器将输入信号解码为一个8位数据,并在解码过程中检查错误。在 `COMMA` 状态下,解码器将输入信号解码为一个逗号,并检查错误。在任何候,如果输入信号无法匹配任何编码,则解码器将输出 `code_err = 2'b01` 来指示错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值