Page MenuHomePhabricator

Adapt rdf-spark-tools to split the wikidata graph based on a set of rules
Closed, ResolvedPublic13 Estimated Story Points

Description

The rdf-spark-tools has a set of tools to import and munge a wikidata dump. This process makes the wikibase RDF graph available in hive as a simple table with four columns:

  • context: generally the entity URI allowing to rapidly group the triples belonging to an entity, minus Values and References which are grouped together
  • subject
  • predicate
  • object

Splitting the graph might not be entirely trivial if applied directly on the dump files (given how values and references are managed) and thus applying a split process on top of the hive table mentioned above might be more appropriate.

The object of this task is to write a new program in rdf-spark-tools that takes wikibase_rdf partition as an input and will output two partitions:

  • wikidata_main (name TBD)
  • scholarly_articles

These two subgraphs must follow the same rules evaluated in T342111:

  • scholarly_articles: direct instanceof Q13442814
  • wikidata_main: the rest

Special care must be taken to properly carry references and values which can be shared across subgraphs.
Ideally the code must be flexible enough that the rules definition can slightly change without requiring to fully change the whole program.

AC:

  • a new program to generate this split is available from rdf-spark-tools
  • a manual dag (or an automated one) is available in the search airflow instance

Event Timeline

Gehel set the point value for this task to 13.Oct 9 2023, 3:55 PM

Personalized dev environment on analytics cluster with Airflow setup (stat1006) - was able to execute job, slightly hacked up to get specific dates and not keep running regularly (eats lots of disk) to get dr0ptp4kt.wikibase_rdf_with_split using my Kerberos principal. Verifying Jupyter notebook approach from David / Andy on stat1005 - some glitches as to be expected, but worked okay by doubling timeouts and removing some caps. Next up, working on a job that will do the splitting in a fashion similar to what's achieved with the join-antijoin approach of the notebooks. I'll want to have the produced data separated out from the existing table, I think - in this case it would be okay in my opinion to use some extra disk.

TL;DR this is about 45% done.

This week I was working to address non-performant, often hanging or crashy, Spark runs. Last night I managed to get this running better, producing a reduction (the equivalent of val_triples_only_used_by_sas from https://people.wikimedia.org/~andrewtavis-wmde/T342111_spark_sa_subgraph_metrics.html ) in 8 minutes in one pass - instead of 3 hours or, worse, something longer followed by an indefinite hang or crash.

The key here was a couple things. First, higher resource limits (this seems obvious, but isn't always true) and attempting to prevent Spark from broadcast joins (it still tries to do them based on the Spark web UI's DAGs, but doesn't seem to do them at bad times, at least).

"spark.driver.memory": "16g",
"spark.driver.cores": 2,
"spark.executor.memory": "12g",
"spark.executor.cores": 4,
"spark.executor.memoryOverhead": "4g",
"spark.sql.shuffle.partitions": 512,
'spark.dynamicAllocation.maxExecutors': 128,
'spark.locality.wait': '1s', # test 0
'spark.sql.autoBroadcastJoinThreshold': -1

Second, removal of cache() calls and setting some join tables as their own DataFrames. This means likely in practice more disk-based merge behavior on the executors for huge joins, but it works better. I'm interested to explore bucketing as an optimization strategy, but may forego this for production of the table as it doesn't seem necessary at the moment - it may however be useful for the produced table for people doing further join operations so am thinking about this.

I had the small reduction pushing to a Parquet directory in HDFS last night. I will be working to see how performant and reliable pushing a larger data set is and will report back here. From there I'll port from Python to Scala.

It took about 26min 24s to write S_direct_triples (7_293_925_470 rows) in basic Parquet. It's not all the rows (not even for its own partition, as that will include Value and Reference triples as well), but this means it ought to be possible for the job to write total 15B rows with about an hour of wall time (maybe double that to play it safe).

Update: it seems to be working. Thus, I'd say this is maybe 75% complete.

It takes about 1h40m to run and generate the two different partitions.

WIP/Draft patches posted at https://gerrit.wikimedia.org/r/c/wikidata/query/rdf/+/969229 and ^ . They require some refactoring and introduction of tests, and probably some extra config variables - I'll connect with Joseph about that last part.

David, Erik, and I spoke through things earlier today while I opened the repos in my IDE. I'll request code review so I can iterate on this.

Here's what I saw after re-running. So, we should be good with the latest patchset that goes without distinct() on the final graphs.

Without distinct() on final graphs - 1h48m
[dr0ptp4kt.wikibase_rdf_scholarly_split_refactor_no_distinct_less_cache]
scholarly_articles: 7_643_858_365, wikidata_main: 7_677_112_695

With distinct() on final graphs - 1h55m
[dr0ptp4kt.wikibase_rdf_scholarly_split_refactor_using_distinct_less_cache]
scholarly_articles: 7_643_858_365, wikidata_main: 7_677_112_695

During discussion today we figured we should be able to merge, then do a JAR release, then update the Airflow patch to use the right version, and get this onto the Search Airflow instance. So, will tentatively plan for that for tomorrow.

Spark patch merged, new Jenkins build of the rdf JAR done, Airflow patch merged. This is deployed to Search's Airflow instance and the job is running. Thank you, @dcausse and @EBernhardson.

Here's the location of stuff for this job that's currently running.

--deploy-mode cluster hdfs:///wmf/cache/artifacts/airflow/search/rdf-spark-tools-0.3.137-jar-with-dependencies.jar
--input-table-partition-spec discovery.wikibase_rdf_t337013/date=20231016/wiki=wikidata
--output-table-partition-spec discovery.wikibase_rdf_scholarly_split/snapshot=20231016/wiki=wikidata
max_attempts: 1

The job completed. The counts match up on this productionized job compared with the prior one run in my namespace. Following are some Hive queries in case needed later. Below that is a really small sample of the resultant data in tabular format for each partition.

Counts

select count(1) from discovery.wikibase_rdf_scholarly_split where snapshot = '20231016' and wiki = 'wikidata' and
scope = 'scholarly_articles';
7643858365
select count(1) from discovery.wikibase_rdf_scholarly_split where snapshot = '20231016' and wiki = 'wikidata' and
scope = 'wikidata_main';
7677112695

Samples

Note: because the target sample size is so small, it's actually possible to get slightly less than the target number of records due to sparseness in a randomly selected set. One can compensate by setting the numerator higher or the denominator lower if one likes to reduce the possibility of such potential artifacts (e.g., to avoid getting 27 records when one really wants 30 records; below we get 30 records apiece, mind you). Note the horizontal scrollbars at the bottom of the tabular data in case the tables overflow on one's browser's settings in Phabricator (mine do).

EDIT: note that there are < and > symbols in the cell values for URIs. (see the Phab source for reference - I won't run the query again, but it would be possible to concatenate to code format or encode these symbols so they render in a table context in Phab).

select "| " || concat_ws(" | ", subject, predicate, object, context) from discovery.wikibase_rdf_scholarly_split where snapshot = '20231016' and wiki = 'wikidata' and
scope = 'scholarly_articles' and rand() <= (30/7643858365) distribute by rand() sort by rand() limit 30;

subjectpredicateobjectcontext
http://www.wikidata.org/entity/statement/Q114851466-BB650063-6818-4AF5-88FD-743A5520811Chttp://www.w3.org/ns/prov#wasDerivedFromhttp://www.wikidata.org/reference/a84e44b8b704dd021b87b792549c1623fc1edff3http://www.wikidata.org/entity/Q114851466
http://www.wikidata.org/entity/statement/Q73327727-EE2DF999-D668-4D6A-860F-B5FE8B93747Ehttp://wikiba.se/ontology#rankhttp://wikiba.se/ontology#NormalRankhttp://www.wikidata.org/entity/Q73327727
http://www.wikidata.org/entity/Q45987415http://www.wikidata.org/prop/direct/P407http://www.wikidata.org/entity/Q1860http://www.wikidata.org/entity/Q45987415
http://www.wikidata.org/entity/statement/Q44327803-9B2ED327-7B22-41B3-927D-F0D780F14C63http://wikiba.se/ontology#rankhttp://wikiba.se/ontology#NormalRankhttp://www.wikidata.org/entity/Q44327803
http://www.wikidata.org/entity/Q40775359http://schema.org/description"\u043D\u0430\u0443\u0447\u043D\u0430\u044F \u0441\u0442\u0430\u0442\u044C\u044F"@ruhttp://www.wikidata.org/entity/Q40775359
http://www.wikidata.org/entity/statement/Q33904556-172A1324-DF02-4555-AC23-CD26DED1A182http://www.wikidata.org/prop/statement/P304"49-52"http://www.wikidata.org/entity/Q33904556
http://www.wikidata.org/entity/Q21994578http://schema.org/description"wetenschappelijk artikel (gepubliceerd op 2009/10/09)"@nlhttp://www.wikidata.org/entity/Q21994578
http://www.wikidata.org/entity/statement/Q93701619-747BA9CD-B887-4755-A744-01607FD15567http://wikiba.se/ontology#rankhttp://wikiba.se/ontology#NormalRankhttp://www.wikidata.org/entity/Q93701619
http://www.wikidata.org/entity/statement/Q42812060-1DBF45B2-E920-4CF6-8011-A94820FF10EAhttp://wikiba.se/ontology#rankhttp://wikiba.se/ontology#NormalRankhttp://www.wikidata.org/entity/Q42812060
http://www.wikidata.org/entity/statement/Q36819529-349D4DA8-BC3D-4B01-90F4-C5D42F4E3683http://www.wikidata.org/prop/statement/P50http://www.wikidata.org/entity/Q58034888http://www.wikidata.org/entity/Q36819529
http://www.wikidata.org/entity/Q44858419http://www.wikidata.org/prop/direct/P2860http://www.wikidata.org/entity/Q36317712http://www.wikidata.org/entity/Q44858419
http://www.wikidata.org/entity/Q60362876http://www.wikidata.org/prop/direct/P31http://www.wikidata.org/entity/Q13442814http://www.wikidata.org/entity/Q60362876
http://www.wikidata.org/entity/Q40459695http://schema.org/description"2016\u5E74\u8AD6\u6587"@zh-hkhttp://www.wikidata.org/entity/Q40459695
http://www.wikidata.org/entity/Q71273478http://www.wikidata.org/prop/direct/P304"100-112"http://www.wikidata.org/entity/Q71273478
http://www.wikidata.org/entity/Q76599804http://www.wikidata.org/prop/P304http://www.wikidata.org/entity/statement/Q76599804-4D1E857D-9A6D-4A20-8A83-21171E49D445http://www.wikidata.org/entity/Q76599804
http://www.wikidata.org/entity/statement/Q83330874-68AEEE6D-2713-4C17-9302-FD9B8D321C6Dhttp://www.w3.org/1999/02/22-rdf-syntax-ns#typehttp://wikiba.se/ontology#BestRankhttp://www.wikidata.org/entity/Q83330874
http://www.wikidata.org/entity/statement/Q69606657-7DB05490-352E-484E-AA83-14736FB97FDFhttp://www.w3.org/ns/prov#wasDerivedFromhttp://www.wikidata.org/reference/7ed4e1f8a263e1b76f533d7a87b490857b67e03fhttp://www.wikidata.org/entity/Q69606657
http://www.wikidata.org/entity/statement/Q90202645-4FF5BDC1-BA1F-4B42-93E1-E954F0268F4Chttp://www.w3.org/1999/02/22-rdf-syntax-ns#typehttp://wikiba.se/ontology#BestRankhttp://www.wikidata.org/entity/Q90202645
http://www.wikidata.org/entity/statement/Q40660107-7BF920C3-C7C1-41C3-94DE-2504A23A8858http://www.w3.org/1999/02/22-rdf-syntax-ns#typehttp://wikiba.se/ontology#BestRankhttp://www.wikidata.org/entity/Q40660107
http://www.wikidata.org/entity/Q34775130http://schema.org/description"articol \u0219tiin\u021Bific"@rohttp://www.wikidata.org/entity/Q34775130
http://www.wikidata.org/reference/3266ceb219f19908f6f1b964a51312a25a9604c3http://www.wikidata.org/prop/reference/P698"1837481"http://wikiba.se/ontology#Reference
http://www.wikidata.org/entity/statement/Q47377036-3B9BB36D-E9E5-4639-B080-CAD2AD17C760http://www.w3.org/ns/prov#wasDerivedFromhttp://www.wikidata.org/reference/4713db7a27cd249fe1ebe4fc2883bd2d2304829ahttp://www.wikidata.org/entity/Q47377036
http://www.wikidata.org/entity/statement/Q94568867-53F34F65-200F-43FB-B96A-D3D4C09259F8http://wikiba.se/ontology#rankhttp://wikiba.se/ontology#NormalRankhttp://www.wikidata.org/entity/Q94568867
http://www.wikidata.org/entity/statement/Q56877680-F96C1513-9A28-44AF-AF11-377FCF292FE0http://www.wikidata.org/prop/qualifier/P1545"1"http://www.wikidata.org/entity/Q56877680
http://www.wikidata.org/entity/Q47320305http://www.wikidata.org/prop/direct/P2860http://www.wikidata.org/entity/Q51932141http://www.wikidata.org/entity/Q47320305
http://www.wikidata.org/entity/statement/Q37867076-CFE94A3E-78EE-4F5B-8974-E6B17EC7C388http://wikiba.se/ontology#rankhttp://wikiba.se/ontology#NormalRankhttp://www.wikidata.org/entity/Q37867076
http://www.wikidata.org/entity/statement/Q59070330-9049FADB-B493-4076-877C-92C481788810http://www.wikidata.org/prop/qualifier/P1545"3"http://www.wikidata.org/entity/Q59070330
http://www.wikidata.org/entity/statement/Q36790547-0FE3E519-6324-42CD-B8B6-F0EE9D67F035http://www.w3.org/1999/02/22-rdf-syntax-ns#typehttp://wikiba.se/ontology#BestRankhttp://www.wikidata.org/entity/Q36790547
http://www.wikidata.org/entity/statement/Q51084018-02E2B751-4299-4BCC-B0C7-D989395A3277http://wikiba.se/ontology#rankhttp://wikiba.se/ontology#NormalRankhttp://www.wikidata.org/entity/Q51084018
http://www.wikidata.org/entity/Q107339531http://schema.org/description"scholarly article"@enhttp://www.wikidata.org/entity/Q107339531
select "| " || concat_ws(" | ", subject, predicate, object, context) from discovery.wikibase_rdf_scholarly_split where snapshot = '20231016' and wiki = 'wikidata' and
scope = 'wikidata_main' and rand() <= (30/7677112695) distribute by rand() sort by rand() limit 30;

subjectpredicateobjectcontext
http://www.wikidata.org/entity/Q49807406http://www.wikidata.org/prop/P625http://www.wikidata.org/entity/statement/Q49807406-66AF95D0-4518-42E9-9937-DCCE6556429Ehttp://www.wikidata.org/entity/Q49807406
http://www.wikidata.org/entity/statement/Q85378574-2947160E-F8C8-4313-8950-BC28CE1BED41http://www.wikidata.org/prop/statement/P1215"+9.701"^^http://www.w3.org/2001/XMLSchema#decimalhttp://www.wikidata.org/entity/Q85378574
http://www.wikidata.org/entity/Q108292558http://www.w3.org/2000/01/rdf-schema#label"Pseudocercospora hemidesmi"@exthttp://www.wikidata.org/entity/Q108292558
http://www.wikidata.org/entity/statement/Q50725055-D207E8C9-0BF9-42A1-A4F2-E5C5974DBA6Fhttp://www.w3.org/1999/02/22-rdf-syntax-ns#typehttp://wikiba.se/ontology#BestRankhttp://www.wikidata.org/entity/Q50725055
http://www.wikidata.org/entity/Q110491797http://www.wikidata.org/prop/direct/P7715"wfo-0000539087"http://www.wikidata.org/entity/Q110491797
http://www.wikidata.org/entity/Q32331573http://schema.org/description"kategori Wikim\u00E9dia"@suhttp://www.wikidata.org/entity/Q32331573
http://www.wikidata.org/entity/Q105545263http://wikiba.se/ontology#sitelinks"0"^^http://www.w3.org/2001/XMLSchema#integerhttp://www.wikidata.org/entity/Q105545263
http://www.wikidata.org/entity/statement/Q115169651-DDA3021D-BB03-4C7D-AD4F-B54D1FD469B0http://www.w3.org/ns/prov#wasDerivedFromhttp://www.wikidata.org/reference/cfbc5fe327f2c100c50be6ad2106edaf471ea3fahttp://www.wikidata.org/entity/Q115169651
http://www.wikidata.org/entity/Q5627219http://www.wikidata.org/prop/P625http://www.wikidata.org/entity/statement/Q5627219-80E983C1-D244-415A-85C9-0479297CAB67http://www.wikidata.org/entity/Q5627219
http://www.wikidata.org/entity/Q24710751http://schema.org/description"Wikinews-artikel"@svhttp://www.wikidata.org/entity/Q24710751
https://zh.wikisource.org/wiki/%E7%A4%BE%E4%BC%9A%E6%8A%9A%E5%85%BB%E8%B4%B9%E5%BE%81%E6%94%B6%E7%AE%A1%E7%90%86%E5%8A%9E%E6%B3%95http://schema.org/abouthttp://www.wikidata.org/entity/Q63874217http://www.wikidata.org/entity/Q63874217
http://www.wikidata.org/entity/Q32939004http://schema.org/description"\u062A\u0635\u0646\u064A\u0641 \u0628\u062A\u0627\u0639 \u0648\u064A\u0643\u064A\u0645\u064A\u062F\u064A\u0627"@arzhttp://www.wikidata.org/entity/Q32939004
http://www.wikidata.org/entity/statement/Q23181334-0C2D5667-CBCA-4DBF-879A-F6B15404D680http://www.wikidata.org/prop/qualifier/P1057http://www.wikidata.org/entity/Q50391046http://www.wikidata.org/entity/Q23181334
http://www.wikidata.org/entity/statement/Q18301925-6FA6F7B4-33C2-4F0F-9B4B-742D5FB30370http://www.w3.org/1999/02/22-rdf-syntax-ns#typehttp://wikiba.se/ontology#BestRankhttp://www.wikidata.org/entity/Q18301925
http://www.wikidata.org/entity/statement/Q112070716-F836DC17-73CD-42F4-BC08-B46509EEABA7http://www.wikidata.org/prop/statement/P131http://www.wikidata.org/entity/Q785208http://www.wikidata.org/entity/Q112070716
http://www.wikidata.org/entity/Q65729373http://schema.org/description"kategori Wikim\u00E9dia"@suhttp://www.wikidata.org/entity/Q65729373
https://zh-yue.wikipedia.org/wiki/%E6%91%A9%E5%BE%B7%E7%B4%8Dhttp://schema.org/name"\u6469\u5FB7\u7D0D"@yuehttp://www.wikidata.org/entity/Q279
http://www.wikidata.org/entity/Q65926032http://schema.org/description"\u0442\u0435\u043A, \u0430\u0442\u0430-\u0442\u0435\u043A, \u04D9\u0443\u043B\u0435\u0442 \u0435\u0441\u0456\u043C"@kk-cyrlhttp://www.wikidata.org/entity/Q65926032
http://www.wikidata.org/entity/statement/q3066762-57632F77-2ABD-400D-B1E3-276C4A931738http://www.w3.org/1999/02/22-rdf-syntax-ns#typehttp://wikiba.se/ontology#BestRankhttp://www.wikidata.org/entity/Q3066762
http://www.wikidata.org/entity/Q83560496http://schema.org/dateModified"2023-04-03T23:30:11Z"^^http://www.w3.org/2001/XMLSchema#dateTimehttp://www.wikidata.org/entity/Q83560496
http://www.wikidata.org/entity/statement/Q337782-58ED5EAD-4B59-4480-943A-8CF9C54FF842http://www.wikidata.org/prop/statement/P625"Point(17.47638889 48.27083333)"^^http://www.opengis.net/ont/geosparql#wktLiteralhttp://www.wikidata.org/entity/Q337782
http://www.wikidata.org/reference/14f0d027b29850b0e4d6342d63314a8fab09ef14http://www.wikidata.org/prop/reference/value/P813http://www.wikidata.org/value/3cd7e8cd5e5b054a043e175e93e8c62chttp://wikiba.se/ontology#Reference
http://www.wikidata.org/entity/Q21058424http://schema.org/description"Wikimedia-categorie"@lihttp://www.wikidata.org/entity/Q21058424
http://www.wikidata.org/entity/Q22416145http://wikiba.se/ontology#sitelinks"1"^^http://www.w3.org/2001/XMLSchema#integerhttp://www.wikidata.org/entity/Q22416145
http://www.wikidata.org/entity/Q5736159http://www.wikidata.org/prop/direct/P17http://www.wikidata.org/entity/Q794http://www.wikidata.org/entity/Q5736159
http://www.wikidata.org/entity/Q88698249http://schema.org/description"kategori Wikimedia"@jvhttp://www.wikidata.org/entity/Q88698249
http://www.wikidata.org/value/48435e14b063af39dcd5b3fa1a93b809http://wikiba.se/ontology#quantityAmount"+0.8465448252131576106747699141154275660042082174200357"^^http://www.w3.org/2001/XMLSchema#decimalhttp://wikiba.se/ontology#Value
http://www.wikidata.org/entity/Q65105814http://www.w3.org/2004/02/skos/core#altLabel"Guttin"@zh-myhttp://www.wikidata.org/entity/Q65105814
http://www.wikidata.org/entity/Q66478013http://www.wikidata.org/prop/direct/P625"Point(-2.1130284786468 55.742360250329)"^^http://www.opengis.net/ont/geosparql#wktLiteralhttp://www.wikidata.org/entity/Q66478013
http://www.wikidata.org/entity/Q55812113http://www.w3.org/2004/02/skos/core#altLabel"20.22"@nbhttp://www.wikidata.org/entity/Q55812113
dr0ptp4kt triaged this task as High priority.