Skip to content

Commit 54ec0d1

Browse files
ikreymertw4l
andauthored
Dedupe docs (#989)
- Adds 'Deduplication' page to cover info about dedupe and indexer entrypoint. - Add 'indexer' section to CLI flags page. - Put User Docs before Develop in docs menu --------- Co-authored-by: Tessa Walsh <tessa@bitarchivist.net>
1 parent 743630a commit 54ec0d1

5 files changed

Lines changed: 173 additions & 5 deletions

File tree

docs/docs/user-guide/cli-options.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,3 +380,22 @@ Options:
380380
--sshProxyKnownHostsFile path to SSH known hosts file for SOCKS5 over SSH pro
381381
xy connection [string]
382382
```
383+
## indexer
384+
385+
```
386+
387+
Options:
388+
--help Show help [boolean]
389+
--version Show version number [boolean]
390+
--redisDedupeUrl URL for remote redis instance to index into
391+
[string] [required]
392+
--sourceUrl Source WACZ or Multi WACZ or Multi WACZ JSON to index
393+
[string]
394+
--sourceCrawlId If single WACZ, use this id as source id [string]
395+
--removing If set, also remove unused crawls/hashes from index
396+
[boolean] [default: false]
397+
--commitCrawlId If provided, commit single uncommitted crawl to merged index
398+
and exit [string]
399+
--cancelCrawlId If provided, delete data for uncommitted crawl and exit
400+
[string]
401+
```

docs/docs/user-guide/dedupe.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Deduplication
2+
3+
With version 1.12, the crawler includes full support for deduplication ("dedupe") of crawled content by content hash,
4+
avoiding saving the same content multuple times. When a duplicate is encountered, the crawler saves a reference to the original content, instead of the full response. The crawler supports deduplication in several ways.
5+
6+
## Automatic deduplication within a single crawl
7+
8+
By default, the crawler applies the following deduplication automatically:
9+
10+
- URL-based deduplication: If the same URL is encountered multiple times in a single crawl, the URL is automatically skipped, no revisit record is written.
11+
- Content-based deduplication: If a URL that points to the same *content*, but at a different URL is encountered, a `revisit` record is written,
12+
pointing to the first URL that has the same content. This allows for deduplication of the same content even across different URLs.
13+
14+
## Deduplication across multiple crawls
15+
16+
The crawler also supports content-based deduplication by content across multiple crawls, with an external Redis (or Redis-compatible database) index used to store the deduplication data.
17+
18+
To enable, add `--redisDedupeUrl <redis url>` with a standard Redis format URL `redis://host:port/db`, e.g. `--redisDedupeUrl redis://my-dedupe-index:6379/0`.
19+
20+
Unlike the internal Redis index which is designed for the lifetime of a single crawl, this index is expected to persist accross crawls and is expected to hold all the unique hashes across many crawls.
21+
22+
When enabled, the external index will store the hashes of HTTP content that has previously been archived. For each URL crawled, it'll store the unique hash and first URL and timestamp of that URL in the index. If the hash has already
23+
been archived, it will not be saved again, instead a [`revisit` record will be created](#warc) instead.
24+
25+
!!! tip "Using Kvrocks instead of Redis"
26+
27+
While the index needs to be Redis-compatible, any Redis-compatible database can be used as well without additional changes. [Apache Kvrocks](https://kvrocks.apache.org/) is a good choice for the dedupe index database as it persists the data on disk, instead of keeping it all in memory like Redis.
28+
29+
When multiple crawls are running at the same time, the resources from one crawl are not yet available to the other crawls.
30+
This is to account for crawls that may be cancelled or fail.
31+
32+
Once a crawl is complete, its data is fully 'committed' to the index and available to be deduplicated against by future crawls. This happens automatically when running the crawler via command line but can also be triggered [via a special indexer command](#committing-finished-crawls-to-the-index).
33+
34+
### Example: Running crawls with deduplication
35+
36+
Here's a quick example of running crawls with dedupe against the same index:
37+
38+
1) Start Redis server, e.g. `redis-server -p 10000`
39+
40+
2) Run a crawl with `--redisDedupeUrl` set, e.g. a crawl of 5 pages from `https://old.webrecorder.net/`:
41+
42+
```sh
43+
docker run -it webrecorder/browsertrix-crawler crawl --redisDedupeUrl redis://localhost:10000/0 --url https://old.webrecorder.net/ --generateWACZ --collection firstCrawl --limit 5
44+
```
45+
46+
3) Run a second crawl with same settings:
47+
48+
```sh
49+
docker run -it webrecorder/browsertrix-crawler crawl --redisDedupeUrl redis://localhost:10000/0 --url https://old.webrecorder.net/ --generateWACZ --collection secondCrawl --limit 5
50+
```
51+
52+
The second crawl should be significantly smaller than the first, as duplicate content is not written. Instead, much smaller [`revisit` records](#warc) are added for each URL that was already crawled in the first crawl.
53+
54+
55+
## Create deduplication index from existing crawls
56+
57+
It may sometimes be useful to populate the dedupe index with existing data, e.g. one or more WACZ files of previous crawls. This can be done by reading through all the entries in the CDXJ index inside of a WACZ and populating the dedupe index based on this data.
58+
59+
60+
The crawler also includes a new dedicated entrypoint, `indexer`, to support this operation.
61+
62+
For example, given an existing WACZ file `my-crawl.wacz`:
63+
64+
1) Run the indexer import:
65+
66+
```sh
67+
docker run -it webrecorder/browsertrix-crawler index --sourceUrl my-crawl.wacz --redisDedupeUrl redis://localhost:10000/0
68+
```
69+
70+
This will populate the dedupe index with all the content of `my-crawl.wacz`.
71+
72+
2) It is now possible to run crawls against the deduplication index, e.g.:
73+
74+
```sh
75+
docker run -it webrecorder/browsertrix-crawler crawl --redisDedupeUrl redis://localhost:10000/0 ...
76+
```
77+
78+
### Removing data from deduplication index
79+
80+
By default, the `indexer` operation is additive only, meaning that crawl data is added, but not removed.
81+
To remove all crawls that aren't part of `--sourceUrl` (either single WACZ or a JSON specifying multiple WACZs),
82+
also add the `--remove` flag. This will purge all data that is not being added.
83+
84+
For a complete list of indexer CLI flags, see [indexer CLI flags](cli-options/#indexer).
85+
86+
### Committing finished crawls to the index
87+
88+
By default, the crawler will automatically commit finished crawls to the dedupe index.
89+
However, when running in Kubernetes (usually using the `--restartsOnError` flag), the dedupe index
90+
must be committed manually, since the crawl may be running in multiple instances or may be interrupted
91+
and restarted (or cancelled later).
92+
93+
To commit a finished crawl, run:
94+
95+
```sh
96+
docker run -it webrecorder/browsertrix-crawler indexer --commitCrawlId <crawl-id> --redisDedupeUrl ...
97+
```
98+
99+
The commit process may take a long time if it was a large crawl, but generally should finish quickly.
100+
101+
### Handling interrupted or canceled crawls
102+
103+
If a crawler is interrupted, eg. with SIGINT, the dedupe data stored for that crawl will not yet committed.
104+
Since the crawl has not finished, the user may or may not want to include the data in the dedupe index.
105+
106+
To include the partially finished crawl, run the above command with `--commitCrawlId`.
107+
108+
To instead clean up the partially finished / interrupted crawls dedupe data, you can also run:
109+
110+
```sh
111+
docker run -it webrecorder/browsertrix-crawler indexer --cancelCrawlId <crawl-id> --redisDedupeUrl ...
112+
```
113+
114+
This operational is not required - the data from the interrupted crawl will not be used in further dedupe, it will
115+
simply free up the data on the Redis.
116+
117+
118+
## Deduplication outputs
119+
120+
When deduplication is enabled, the crawler output is changed in the following ways (in addition to using
121+
less disk storage overall):
122+
123+
### WARC
124+
125+
The crawler will write WARC `revisit` records to indicate
126+
that a particular HTTP response has already been crawled. These records include a reference to the URL and timestamp
127+
of the original WARC `response` record, which includes the full content.
128+
129+
HTTP headers are not deduplicated and are included in the `revisit` records.
130+
131+
### WACZ
132+
133+
When using deduplication, the crawler also stores dependency information between WACZ files, tracking which WACZ
134+
file(s) contain the WARCs with `response` records for each `revisit` record that is written.
135+
This allows for tracking which WACZ files are required by other WACZ files to get the full archived content.
136+
See the [WACZ dependency section of the developer documentation](../develop/dedupe.md#crawl-dependency-tracking-in-wacz-datapackagejson) for more details on the architecture of this dependency system.
137+
138+
## Deduplication system architecture
139+
See the [developer docs for dedupe](../develop/dedupe.md) for more advanced information of the architecture of the dedupe system.

docs/gen-cli.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,24 @@ echo "# All Command-Line Options" > $out
66
echo "" >> $out
77
echo "The Browsertrix Crawler Docker image currently accepts the following parameters, broken down by entrypoint:" >> $out
88
echo "" >> $out
9+
910
echo "## crawler" >> $out
1011
echo "" >> $out
1112
echo '```' >> $out
1213
#node $CURR/../dist/main.js --help >> $out
1314
docker run webrecorder/browsertrix-crawler crawl --help | tail -n +3 >> $out
1415
echo '```' >> $out
1516
echo "" >> $out
17+
1618
echo "## create-login-profile" >> $out
1719
echo "" >> $out
1820
echo '```' >> $out
1921
docker run webrecorder/browsertrix-crawler create-login-profile --help | tail -n +3 >> $out
2022
echo '```' >> $out
23+
24+
25+
echo "## indexer" >> $out
26+
echo "" >> $out
27+
echo '```' >> $out
28+
docker run webrecorder/browsertrix-crawler indexer --help | tail -n +3 >> $out
29+
echo '```' >> $out

docs/mkdocs.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ theme:
4545

4646
nav:
4747
- index.md
48-
- Develop:
49-
- develop/index.md
50-
- develop/docs.md
51-
- develop/dedupe.md
5248
- User Guide:
5349
- user-guide/index.md
5450
- user-guide/outputs.md
@@ -57,10 +53,15 @@ nav:
5753
- user-guide/crawl-scope.md
5854
- user-guide/yaml-config.md
5955
- user-guide/browser-profiles.md
56+
- user-guide/dedupe.md
6057
- user-guide/proxies.md
6158
- user-guide/behaviors.md
6259
- user-guide/qa.md
6360
- user-guide/cli-options.md
61+
- Develop:
62+
- develop/index.md
63+
- develop/docs.md
64+
- develop/dedupe.md
6465

6566
markdown_extensions:
6667
- toc:

src/indexer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class CrawlIndexer {
5454
},
5555

5656
removing: {
57-
describe: "If set, also remove unsued crawls/hashes from index",
57+
describe: "If set, also remove unused crawls/hashes from index",
5858
type: "boolean",
5959
required: false,
6060
default: false,

0 commit comments

Comments
 (0)