Skip to content

Commit e9c4ff9

Browse files
committed
add translated for ''
1 parent bb4ef3b commit e9c4ff9

5 files changed

Lines changed: 155 additions & 317 deletions

Others/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,6 @@
7777

7878
- [逆向工程我的酒店中的一个神秘的UDP流](./逆向工程我的酒店中的一个神秘的UDP流.md)
7979

80-
额,不说了,挺好玩的……
80+
额,不说了,挺好玩的……
81+
82+
- [记录每天数以百万计的请求以及需要采取哪些措施](./记录每天数以百万计的请求以及需要采取哪些措施.md)
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
原文: [Logging millions of requests everyday and what it takes](http://engineering.hackerearth.com/2015/02/26/logging-millions-requests-what-it-takes/)
2+
3+
---
4+
5+
HackerEarth的web服务器每天处理数以百万计的请求。这些请求日志可以用来分析挖掘一些对关键业务非常有用的见解和指标,例如,每天的浏览量,每个子产品的浏览量,最受欢迎的用户导航流程等等。
6+
7+
### 最初的想法
8+
9+
HackerEarth使用Django作为其主要WEB开发框架,并保存一些为性能和可扩展性定制的部件。在正常运行期间,我们的服务器平均每秒处理80-90个请求,而当多个竞争在一个时间差上重叠时,这会激增到每秒200-250个请求。我们需要一个系统,它能够很容易的扩展以满足高峰期流量每秒500个请求。另外,该系统应该添加最小处理开销到web服务器上,而收集到的数据应该存储以用于运算和离线处理。
10+
11+
### 架构
12+
13+
![](http://engineering.hackerearth.com/images/logging_architecture.png)
14+
15+
上图显示了我们的请求日志收集系统的高层体系结构。实线代表不同组件之间的数据流,而虚线代表不同组件之间的通信。整个架构是基于消息和无状态,因此各个组件可以很容易地被移除/替换,而无需停机。
16+
17+
下面是一个关于在数据流顺序中的每个元件的更详细解释。
18+
19+
## Web服务器
20+
21+
在web服务器上,我们部署了一个[Django中间件](https://docs.djangoproject.com/en/1.7/topics/http/middleware/),它为给定的请求异步检索所需数据,然后将它转发给Transporter集群服务器。这是通过使用一个线程完成的,而该中间件为Django请求/响应循环添加了2毫秒的开销。
22+
23+
```python
24+
25+
class RequestLoggerMiddleware(object):
26+
"""
27+
Logs data from requests
28+
"""
29+
def process_request(self, request):
30+
if settings.LOCAL or settings.DEBUG:
31+
return None
32+
33+
if request.is_ajax():
34+
is_ajax = True
35+
request.META['IS_AJAX'] = is_ajax
36+
37+
before = datetime.datetime.now()
38+
39+
DISALLOWED_USER_AGENTS = ["ELB-HealthChecker/1.0"]
40+
41+
42+
http_user_agent = request.environ.get('HTTP_USER_AGENT','')
43+
44+
if http_user_agent in DISALLOWED_USER_AGENTS:
45+
return None
46+
47+
# this creates a thread which collects required data and forwards
48+
# it to the transporter cluster
49+
run_async(log_request_async, request)
50+
after = datetime.datetime.now()
51+
52+
log("TotalTimeTakenByMiddleware %s"%((after-before).total_seconds()))
53+
return None
54+
```
55+
56+
## Transporter集群
57+
58+
transporter集群是非阻塞[Thrift](https://thrift.apache.org/)服务器阵列,用于从web服务器接收数据,然后将其路由到任何其他诸如MongoDB, RabbitMQ, Kafka这样的组件这一唯一目的。一条给定的消息应该被路由到哪里是来自于web服务器的消息自身指定的。从web服务器到transporter服务器的通信只有唯一一种方式,而这节省了花费在确认由thrift服务器接收的信息上的一些时间资源。由于这个原因,我们可能会失去一些请求日志,但是这样值得。当前,请求日志被路由到Kafka集群。web服务器和transporter服务器之间的通信平均花费1-2毫秒,并且可以水平缩放以处理负载的增加。
59+
60+
以下是thrift配置文件的一部分。该文件定义了一个DataTransporter服务,支持作为一个修改器的带oneway的方法,这基本上意味着RPC调用将会立即返回。
61+
62+
```python
63+
64+
service DataTransporter {
65+
oneway void transport(1:map<string, string> message)
66+
}
67+
```
68+
69+
## Kafka集群
70+
71+
[Kafka](http://kafka.apache.org/)是一个支持发布/订阅消息模式的高通量分布式消息系统。这种消息传递基础结构使我们能够建立一个依赖于该流请求日志的其他管线。我们的Kafka集群保存15天有意义的日志,所以我们可以让我们实现的任何新的消费者开始处理数据15天内的任何数据。
72+
73+
[创建一个kafka集群的有用参考。](http://www.michael-noll.com/blog/2013/03/13/running-a-multi-broker-apache-kafka-cluster-on-a-single-node/)
74+
75+
## Pipeline管理服务器
76+
77+
这个服务器管理来自Kafka topics的请求日志消息的消费,将其存储在MongoDB中,然后将它们移动到Amazon S3以及[Amazon Redshift](http://aws.amazon.com/redshift/)。MongoDB仅作为从Kafka topics消费的数据的分段区域,而该数据每隔一小时被转移到S3。每个保存到S3的文件被加载到Amazon Redshift这一可以扩展到数据PB级的数据仓库解决方案。我们使用Amazon Redshift来分析/度量来自请求日志数据的计算。该服务器与一个[RabbitMQ](http://www.rabbitmq.com/)集群协同工作,这个集群被用来对任务完成和启动进行通信。
78+
79+
下面是从S3加载数据到Redshift的脚本。该脚本首先通过移除任何重复行,然后插入新数据来处理重复数据的插入。
80+
81+
```python
82+
83+
import os
84+
import sys
85+
import subprocess
86+
87+
from django.conf import settings
88+
89+
90+
def load_s3_delta_into_redshift(s3_delta_file_path):
91+
"""s3_delta_file_path is path after the bucket
92+
name.
93+
"""
94+
bigdata_bucket = settings.BIGDATA_S3_BUCKET
95+
96+
attrs = {
97+
'bigdata_bucket': bigdata_bucket,
98+
's3_delta_file_path': s3_delta_file_path,
99+
}
100+
101+
complete_delta_file_path = "s3://{bigdata_bucket}/{s3_delta_file_path}".format(**attrs)
102+
103+
schema_file_path = "s3://{bigdata_bucket}/request_log/s3_col_schema.json".format(**attrs)
104+
105+
data = {
106+
'AWS_ACCESS_KEY_ID': settings.AWS_ACCESS_KEY_ID,
107+
'AWS_SECRET_ACCESS_KEY': settings.AWS_SECRET_ACCESS_KEY,
108+
'LOG_FILE': complete_delta_file_path,
109+
'schema_file_path': schema_file_path
110+
}
111+
112+
S3_REDSHIFT_COPY_COMMAND = " ".join([
113+
"copy requestlog_staging from '{LOG_FILE}' ",
114+
"CREDENTIALS 'aws_access_key_id={AWS_ACCESS_KEY_ID};aws_secret_access_key={AWS_SECRET_ACCESS_KEY}'",
115+
"json '{schema_file_path}';"
116+
]).format(**data)
117+
118+
119+
LOADDATA_COMMAND = " ".join([
120+
"begin transaction;",
121+
"create temp table if not exists requestlog_staging(like requestlog);",
122+
S3_REDSHIFT_COPY_COMMAND,
123+
'delete from requestlog using requestlog_staging where requestlog.row_id=requestlog_staging.row_id;',
124+
'insert into requestlog select * from requestlog_staging;',
125+
"drop table requestlog_staging;",
126+
'end transaction;'
127+
#'vacuum;' #sorts new data added
128+
])
129+
130+
redshift_conn_args = {
131+
'host': settings.REDSHIFT_HOST,
132+
'port': settings.REDSHIFT_PORT,
133+
'username': settings.REDSHIFT_DB_USERNAME
134+
}
135+
136+
REDSHIFT_CONNECT_CMD = 'psql -U {username} -h {host} -p {port}'.format(**redshift_conn_args)
137+
138+
PSQL_LOADDATA_CMD = '%s -c "%s"'%(REDSHIFT_CONNECT_CMD, LOADDATA_COMMAND)
139+
140+
returncode = subprocess.call(PSQL_LOADDATA_CMD, shell=True)
141+
if returncode !=0:
142+
raise Exception("Unable to load s3 delta file into redshift ",
143+
s3_delta_file_path)
144+
```
145+
146+
## 下一步
147+
148+
对于任何Web应用程序,数据就像金子。若以正确的方式处理,那么它可以提供的洞察以及它可以驱动的增长是惊人的。使用请求日志,可以构建几十个的功能和见解,包括推荐引擎,更好的内容交付,并提高产品的整体构建。所有这一切都有助于使HackerEarth更好的服务于我们的用户。
149+
150+
如果你有任何疑问,或者希望更多地讨论这个架构或者涉及的任意技术,可以给我发邮件:praveen@hackerearth.com

Python Weekly/Python Weekly Issue 247.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ ensembles可以为你的数据集提供一个精度的飞跃。在这篇文章
4545

4646
[记录每天数以百万计的请求以及需要采取哪些措施](http://engineering.hackerearth.com/2015/02/26/logging-millions-requests-what-it-takes/)
4747

48+
[中文版](../Others/记录每天数以百万计的请求以及需要采取哪些措施.md)
49+
4850
[构建一个数据科学文件夹:用数据讲故事](https://www.dataquest.io/blog/data-science-portfolio-project/)
4951

5052
[误植域名编程语言包管理器](http://incolumitas.com/2016/06/08/typosquatting-package-managers/)

raw/Logging millions of requests everyday and what it takes.md

Lines changed: 0 additions & 206 deletions
This file was deleted.

0 commit comments

Comments
 (0)