PTF - Data Export Test Report (Ramsons) [ECS]
Overview
This document contains the results of testing Data Export (MARC BIB) on the Ramsons [ECS] release.
https://folio-org.atlassian.net/browse/PERF-977
Summary
Data Export tests finished successfully on RCON environment using the profiles Default instances export job profile and srs - holdings and items job profile.
Data Export test executed on College tenant only.
Ramsons release results
Data Export:
Default instances export job profile
File with 1k records - 2 seconds
File with 100k records - 1 minute 55 seconds
File with 500k records - 4 minute 26 seconds
srs - holdings and items
File with 1k records - 7 seconds
File with 100k records - 5 minute 13 seconds
File with 500k records - 8 minute 19 seconds
Comparing Quesnelia (previous results) and Ramsons releases results. DE perform better in Ramsons. Improvement depends on file size and job profile.
Default instances export job profile
File with 100k records - 27%
File with 500k records - 36%
srs - holdings and items
File with 100k records - 17%
File with 500k records - 11%
Mod-data-export used most of CPU with Default instances export job profile - 51% and srs - holdings and items - 33% with the 500k records file
Concurrent Data Export testing with srs - holdings and items job profile revealed the slowness on central tenant. It completed with errors on UI side. It should be investigated.
Test Runs
Profile | Test # | CSV File |
|---|---|---|
DE MARC Bib (Default instances export job profile) | 1 | 1k.csv |
2 | 100k.csv | |
3 | 500k.csv | |
DE MARC Bib (srs - holdings and items) | 4 | 1k.csv |
5 | 100k.csv | |
6 | 500k.csv |
Test Results
This table contains durations for Data Export with 2 job profiles.
Profile | CSV File | Tenant College (cs00000int_0001) | |
|---|---|---|---|
Result | Status | ||
DE MARC Bib (Default instances export job profile) | 1k.csv | 0:00:02 | COMPLETED |
100k.csv | 0:01:55 | COMPLETED | |
500k.csv | 0:04:26 | COMPLETED | |
DE MARC Bib (srs - holdings and items) | 1k.csv | 0:00:07 | COMPLETED |
100k.csv | 0:05:13 | COMPLETED | |
500k.csv | 0:08:19 | COMPLETED | |
This table contains durations for Data Export for 3 tenants concurrently (this additional experiment was not in scope of the ticket).
Job Profile | File Size | Central Tenant | College tenant | Professional tenant |
|---|---|---|---|---|
Default instances export job profile | 500k | 00:06:12 | 00:06:35 | no data |
| 100k | 00:04:21 | 00:01:55 | 00:02:31 |
srs - holdings and items | 500k | 00:41:33* | 00:11:44 | no data |
| 100k | 00:33:58* | 00:06:51 | 00:08:09 |
* DE with srs - holdings and items job on central tenant completed with errors (2025-01-31T13:47:10.291+00:00 ERROR ui-data-export.error.instance.noPermission).
Errors
Errors occurred possibly because of central tenant has no items and holding records.
ERROR onsFunctionHolder$18 Location is not found by the given id: null
ItemsResolverService retrieveHoldingsAndItemsByInstanceId
Comparison
This table contains durations comparison between Poppy and Quesnelia releases.
Profile | CSV File | Quesnelia (cs00000int_0001) College tenant | Ramsons (cs00000int_0001) College tenant | DE Duration, DELTA Quesnelia/Ramsons |
Duration (hh:mm:ss) | percent / time | |||
DE MARC Bib (Default instances export job profile) | 1k.csv | 00:00:02 | 00:00:02 | 0.00% / 0 sec |
100k.csv | 00:02:39 | 00:01:55 | -27.67% / 44 sec | |
500k.csv | 00:05:21 | 00:04:26 | -17.13% / 55 sec | |
DE MARC Bib (srs - holdings and items) | 1k.csv | 00:00:05 | 00:00:07 | 40.00% / 2 sec |
100k.csv | 00:08:15 | 00:05:13 | -36.77% / 3 min 2 sec | |
500k.csv | 00:09:22 | 00:08:19 | -11.21% / 1 min 3 sec | |
Resource utilization
Service CPU Utilization
Maximum CPU utilization was in 500k file: Default instances export job profile - 51%, srs - holdings and items - 33%
Service Memory Utilization
Maximum memory consumption was in mod-agreements - 92%, data-export-worker - 86%, mod-data-export - 81%, mod-oa - 75%
DB CPU Utilization
Maximum RDS CPU 500k file: srs - holdings and items job - 32%, Default instances export job - 23%
DB Connections
DB connections - 1173 in average. No spikes with different file size or job profile.
DB load
DE MARC Bib (srs - holdings and items) job profile
DE MARC Bib (Default instances export job profile)
Top SQL-queries
DE MARC Bib (srs - holdings and items) job profile
# | TOP SQL statements - DE MARC Bib (srs - holdings and items) job profile |
|---|---|
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
DE MARC Bib (Default instances export job profile)
# | TOP 5 SQL statements - DE MARC Bib (Default instances export job profile) |
|---|---|
1 |
|
2 |
|
3 |
|
4 |
|
Appendix
Infrastructure
PTF - consortia, okapi based environment |
|---|
|
DB table records size:
Instances where 'source'='MARC' |
|---|
Methodology/Approach
Create job profiles srs - holdings and items if needed.
Data Export tests scenarios use the profiles Default instances export job profile and srs - holdings and items
Run sequentially 1k, 100k, 500k on College member tenant using Default instances export job profile.
Run sequentially 1k, 100k, 500k on College member tenant using srs - holdings and items
Run concurrently 500k on central and member tenant.
To get status and time range for export jobs the query used:
SQL Query
SELECT
jsonb->>'jobProfileName' AS jobProfileName, exported as file_size, started_date - completed_date as duration, jsonb->>'status' AS status
FROM
cs00000int_0001_mod_data_export.job_executions
WHERE
status = 'COMPLETED'
ORDER BY
jsonb->>'completed_date' DESC
LIMIT 10;
Use this python script to check CSV file with instance UUIDs to be unique. It will check all lines, delete duplicated ones if found and rewrite the file. So it takes not longer than a second to execute it.
Py script - unique UUID checker
import csv
def process_uuid_file(file_path):
# Initialize a dictionary to count UUIDs
uuid_counts = {}
# Read the file and count UUID occurrences
with open(file_path, 'r') as file:
lines = file.readlines()
for line in lines:
uuid = line.strip().strip('"') # Remove any quotes or extra whitespace
if uuid:
uuid_counts[uuid] = uuid_counts.get(uuid, 0) + 1
# Count duplicates
duplicate_count = sum(count - 1 for count in uuid_counts.values() if count > 1)
print(f"Total duplicates found: {duplicate_count}")
# Remove duplicates and write back unique UUIDs
unique_uuids = list(uuid_counts.keys())
with open(file_path, 'w') as file:
for uuid in unique_uuids:
file.write(f'"{uuid}"\n')
print(f"File has been updated with {len(unique_uuids)} unique UUIDs.")
# Example usage
file_path = '100k_DE_central.csv' # Replace with your file path
process_uuid_file(file_path)