15 个版本 (破坏性更新)
0.12.0 | 2021 年 6 月 6 日 |
---|---|
0.10.0 | 2021 年 6 月 6 日 |
#595 在 并发
每月 30 次下载
56KB
1.5K SLoC
Crusty - 优雅且可扩展的宽域网络爬虫
简介
宽域网络爬虫是通过从一组位置(urls)开始并跟随外部域的出站链接来遍历几乎无限的网络的活 动。只要它有指向外部域的出站链接,通常起点在哪里并不重要。
它提出了许多挑战,必须克服这些挑战才能获得一个稳定且可扩展的系统,《Crusty》试图解决其中的一些挑战,在享受 Rust 的乐趣的同时看看这里有什么;(;)
这个特定的实现可以用来快速获取可观察互联网的所有子集,例如,发现最受欢迎的域名/链接
基于 crusty-core 构建,该库处理网络爬取的所有低级方面
主要特性
-
可配置性和可扩展性
查看一个典型的 配置文件,其中包含一些有关可用选项的解释
-
快速的单节点性能
Crusty 使用在 tokio 上运行的绿色线程编写,因此即使在中等配置的 PC 上也能实现相当可观的单节点性能
可以进行其他优化来进一步提高此性能(主要是更好的 HTML 解析,有些任务不需要完整的 DOM 解析,这个实现主要为了可扩展性和可配置性而进行完整的 DOM 解析)
Crusty
具有小型、稳定和可预测的内存占用,通常受 CPU/网络限制。没有 GC 压力,没有内存争夺战。 -
可扩展性
每个
Crusty
节点本质上是一个独立的单元,我们可以并行运行数百个(当然是在不同的机器上),难点在于工作委派和域发现,这通过在 clickhouse 上构建的高性能碎片化队列结构来解决(啊!)。有人可能会想“clickhouse?什么鬼?!”但这个数据库非常快(同时提供丰富的查询功能、索引、过滤),所以看起来很合适。
该想法基本上是一个巨大的分片表,其中每个域名(实际上是解析到的IP衍生)都属于某个分片(
crc32(addr) % number_of_shards
),现在每个Crusty
实例可以读取所有这些分片中的唯一子集,同时可以写入所有分片(所谓域名发现)。在中等规模部署(<16节点)中,该系统如目前这样是可行的,尽管如果有人试图将其扩展到巨规模,可能需要动态分片管理器...
在多节点设置中,存在域发现去重方面的额外挑战,- 目前我们在本地和在clickhouse(AggregatingMergeTree)中进行去重,但随着节点数量的增加,本地去重效率降低
在大规模部署中,可能需要专门的去重层,或者可以尝试通过确保有足够的分片和足够的clickhouse实例来满足所需性能,简单地推卸相当多的去重工作到clickhouse
-
基本礼貌
虽然我们可以并行爬取数千个域名,但我们绝对应该限制每个域名的并发量,以避免对爬取网站造成压力,请参阅
job_reader.default_crawler_settings.concurrency
。此外,测试表明,许多完全不同的域名可以存在于同一个物理IP上...所以我们从不尝试从一个IP获取超过job_reader.domain_top_n
个域名在访问页面之间引入延迟也是一个好习惯,请参阅
job_reader.default_crawler_settings.delay
。支持
robots.txt
! -
可观察性
Crusty使用跟踪并在clickhouse中存储多个度量标准,我们可以用grafana观察它们——提供爬取性能的实时洞察
入门
- 在开始之前
安装docker
&& docker-compose
,请遵循以下说明
https://docs.docker.net.cn/get-docker/
https://docs.docker.net.cn/compose/install/
- 玩一玩它
git clone https://github.com/let4be/crusty
cd crusty
# might take some time
docker-compose build
# can use ANY or even several(separated by a comma), example.com works too just has one external link ;)
CRUSTY_SEEDS=https://example.com docker-compose up -d
-
在https://127.0.0.1:3000/d/crusty-dashboard/crusty?orgId=1&refresh=5s上查看
Crusty
的实时状态 -
要停止后台运行并删除爬取数据(clickhouse/grafana),请运行
docker-compose down -v
此外
-
学习配置文件并根据您的需求进行调整,对于100mbit通道,有合理的默认值,如果您有更多/更少的带宽/处理器,您可能需要调整
concurrency_profile
-
要停止后台运行并保留爬取数据,请运行
docker-compose down
-
要运行并附加,并查看所有容器的实时日志(可以按Ctrl+c中止)
CRUSTY_SEEDS=https://example.com docker-compose up
-
要查看正在运行的容器,请运行
docker ps
(应该是3个 -crusty-grafana
,crusty-clickhouse
和crusty
) -
要查看日志:请运行
docker logs crusty
如果您决定通过cargo build
手动构建,请记住 - release
构建要快得多(默认是debug
)
在实际应用场景中,尤其是在高带宽通道上,Docker可能显得有些昂贵,因此直接运行或至少设置 network_mode = host
可能是个好主意。
外部服务依赖 - ClickHouse 和 Grafana
仅使用 docker-compose
,这是推荐的方式来玩耍 Crusty
。
然而...
要创建/清理数据库,请使用此 SQL(必须提供给 ClickHouse 容器中的 clickhouse client
-在上下文中):链接
Grafana 仪表板以 JSON 模型导出:链接
开发
-
确保已安装
rustup
:[https://rustup.rs/](https://rustup.rs/) -
确保已安装
pre-commit
:[https://pre-commit.git-scm.cn/](https://pre-commit.git-scm.cn/) -
运行
./go setup
-
运行
./go check
以运行所有 pre-commit 钩子,并确保一切准备就绪以便进行 git 操作 -
运行
./go release minor
以发布下一个 minor 版本到 crates.io
贡献
我愿意讨论/接受贡献,请使用 github issues,
欢迎 pull requests
依赖
~19–32MB
~513K SLoC