Quickstart Portavita Benchmark¶
This quickstart installs the Portavita Benchmark, a.k.a. AXLE Healthcare Benchmark, in a Docker instance, runs the CDA generator and loads transformed messages into a MGRID HDM database. The configuration used in the configuration of this quickstart has been benchmarked on physical hardware (32 core Xeon, 256GB RAM) up to a database size of 18.5TB.
This configuration uses the dual head setup as is described in the MGRID HDL Documentation.
In this setup, patient, organization and practitioner ‘dimensional’ data updates are sent to the MSG to SQL translator and are loaded in the table-per-RIM class tables. The CDA documents that contain the observation values are sent to the MSG to JSON translator, and are loaded into the highly partitioned JSONB document tables.
Installation¶
A preprequisite of this quickstart is a machine that can run Docker instances. The author uses Docker on CentOS 7. Please consult with the documentation of your linux distribution how to run Docker.
First create a directory in which we will place the Dockerfile and run our AXLE Docker image from.
mkdir axle-docker
cd axle-docker
Now create a file called Dockerfile
and place the following contents into it.
FROM centos:6
RUN yum install -y libffi-devel openssl-devel sudo
RUN rpm -Uvh https://www.softwarecollections.org/repos/rhscl/python27/epel-6-x86_64/noarch/rhscl-python27-epel-6-x86_64-1-2.noarch.rpm
RUN sed -i -e "s/Defaults requiretty.*/ #Defaults requiretty/g" /etc/sudoers
ENV REPO_TOKEN=96724b6ca979aefe928489f63ca13ee320e1dce9369a1723
RUN curl -s https://${REPO_TOKEN}:@www.mgrid.net/quickstart/axle.sh | bash
RUN rm /var/run/supervisord.pid && \
rm /etc/xfm/supervisord/supervisor.sock
This Dockerfile contains instructions to download and run a specialized XFM quickstart script from www.mgrid.net. The script will perform the following steps:
- add appropriate software repositories: EPEL, yum.postgresql.org and MGRID packages from packagecloud.io.
- install PostgreSQL, MGRID HDL, HDM, MSG and XFM.
- install the synthetic data generator that creates FHIR and CDA XML messages.
- create postgresql databases
pond<x>
andlake
.
Note
The REPO_TOKEN is for demonstration purposes only! This quickstart uses a repo-token that is only valid for benchmarking purposes with the Portavita Benchmark. Downloads with this token will get revoked periodically. For development or production tokens to use MGRID software, please contact support@mgrid.net for an appropriate token for your environment.
Build a Docker image called axlec6 using the Dockerfile with the following command. This will take a while.
docker build -t axlec6 -f Dockerfile .
Running the instance¶
Run the image and start a console in it. This will show output like the following:
$ docker run -i -t -p 5432:5432 -P axlec6 bash
[root@7c3f80f62106 /]#
In the instance no services will be currently running. Start sshd
and other components with the following service
commands:
# service sshd start
Starting sshd: [ OK ]
# service supervisord start
Starting supervisord:
axle-ingester:axle-ingester-0 STARTING
xfm-broker:xfm-broker-0 STARTING
xfm-generator:xfm-generator-0 STOPPED Not started
xfm-lake-runner:xfm-lake-runner-0 STOPPED Not started
xfm-lakeserver:xfm-lakeserver-0 STARTING
xfm-loader:xfm-loader-0 STARTING
xfm-pondserver:xfm-pondserver-0 STARTING
xfm-transformer:xfm-transformer-0 STARTING
xfm-transformer-json:xfm-transformer-json-0 STARTING
We can now look at the system a bit, inspect for example the databases, but at this time no data has been generated yet.
$ psql -U xfmuser lake
psql (9.5.0)
Type "help" for help.
lake=# \d
List of relations
Schema | Name | Type | Owner
---------+------------------------------------+----------+---------
hdl | pg_cbinding | table | xfmuser
hdl | pg_code | table | xfmuser
hdl | pg_conceptdomain | table | xfmuser
hdl | pg_oid | table | xfmuser
hdl | pg_oid_seq | sequence | xfmuser
hdl | pg_oidversion | table | xfmuser
hdl | pg_ucumprefix | table | xfmuser
hdl | pg_ucumunit | table | xfmuser
rim2011 | Access | table | xfmuser
rim2011 | Account | table | xfmuser
rim2011 | Acknowledgement | table | xfmuser
rim2011 | AcknowledgementDetail | table | xfmuser
rim2011 | Act | table | xfmuser
rim2011 | ActRelationship | table | xfmuser
rim2011 | Attachment | table | xfmuser
rim2011 | AttentionLine | table | xfmuser
rim2011 | Batch | table | xfmuser
rim2011 | CommunicationFunction | table | xfmuser
rim2011 | Container | table | xfmuser
rim2011 | ContextStructure | table | xfmuser
rim2011 | ControlAct | table | xfmuser
rim2011 | Device | table | xfmuser
rim2011 | DeviceTask | table | xfmuser
rim2011 | DiagnosticImage | table | xfmuser
rim2011 | Diet | table | xfmuser
rim2011 | Document | table | xfmuser
rim2011 | Employee | table | xfmuser
rim2011 | Entity | table | xfmuser
rim2011 | Entity_CommunicationFunction | table | xfmuser
rim2011 | Exposure | table | xfmuser
rim2011 | FinancialContract | table | xfmuser
rim2011 | FinancialTransaction | table | xfmuser
rim2011 | InfrastructureRoot | table | xfmuser
rim2011 | InfrastructureRoot__id_seq | sequence | xfmuser
rim2011 | InvoiceElement | table | xfmuser
rim2011 | LanguageCommunication | table | xfmuser
rim2011 | LicensedEntity | table | xfmuser
rim2011 | LinkActPcpr | table | xfmuser
rim2011 | LivingSubject | table | xfmuser
rim2011 | ManagedParticipation | table | xfmuser
rim2011 | ManufacturedMaterial | table | xfmuser
rim2011 | Material | table | xfmuser
rim2011 | Message | table | xfmuser
rim2011 | NonPersonLivingSubject | table | xfmuser
rim2011 | Observation | table | xfmuser
rim2011 | OptOutConsent | table | xfmuser
rim2011 | Organization | table | xfmuser
rim2011 | Parameter | table | xfmuser
rim2011 | ParameterItem | table | xfmuser
rim2011 | ParameterList | table | xfmuser
rim2011 | Participation | table | xfmuser
rim2011 | Participation_in | table | xfmuser
rim2011 | Patient | table | xfmuser
rim2011 | PatientEncounter | table | xfmuser
rim2011 | Person | table | xfmuser
rim2011 | Place | table | xfmuser
rim2011 | Procedure | table | xfmuser
rim2011 | PublicHealthCase | table | xfmuser
rim2011 | QualifiedEntity | table | xfmuser
rim2011 | QueryAck | table | xfmuser
rim2011 | QueryByParameter | table | xfmuser
rim2011 | QueryContinuation | table | xfmuser
rim2011 | QueryEvent | table | xfmuser
rim2011 | QuerySpec | table | xfmuser
rim2011 | Role | table | xfmuser
rim2011 | RoleLink | table | xfmuser
rim2011 | SortControl | table | xfmuser
rim2011 | SubstanceAdministration | table | xfmuser
rim2011 | Supply | table | xfmuser
rim2011 | Transmission | table | xfmuser
rim2011 | TransmissionRelationship | table | xfmuser
rim2011 | Transmission_CommunicationFunction | table | xfmuser
rim2011 | WorkingList | table | xfmuser
rim2011 | document | table | xfmuser
rim2011 | document_1 | table | xfmuser
rim2011 | document_10 | table | xfmuser
rim2011 | document_100 | table | xfmuser
rim2011 | document_101 | table | xfmuser
rim2011 | document_102 | table | xfmuser
rim2011 | document_103 | table | xfmuser
...etc
rim2011 | document_99 | table | xfmuser
rim2011 | document_sequence | sequence | xfmuser
rim2011 | document_template | table | xfmuser
(476 rows)
lake=# select count(*) from "Act";
count
-------
0
(1 row)
Generating data¶
To start the FHIR and CDA generator, issue the following commands.
# su - xfmadmin
$ xfmctl --role=singlenode supervisor
$ sudo /usr/bin/supervisorctl -c /etc/xfm/supervisord/supervisord.conf start xfm-generator:
In the meantime you can watch the progress by viewing the contents of the RabbitMQ queues.
$ xfmctl --role=singlenode messaging
[127.0.0.1] Executing task 'messaging'
[127.0.0.1] sudo: /opt/mgrid/xfm3-bootstrap/scripts/rabbitmqcmd.py broker list queues
[127.0.0.1] out: +------------+----------------------+-------------+-----------+---------+------------------------+---------------------+---------+----------+----------------+-------------------------+---------------------+--------+---------+
[127.0.0.1] out: | vhost | name | auto_delete | consumers | durable | exclusive_consumer_tag | idle_since | memory | messages | messages_ready | messages_unacknowledged | node | policy | status |
[127.0.0.1] out: +------------+----------------------+-------------+-----------+---------+------------------------+---------------------+---------+----------+----------------+-------------------------+---------------------+--------+---------+
[127.0.0.1] out: | /messaging | dlx-errors-load | False | 0 | True | | 2016-02-01 13:59:16 | 13760 | 0 | 0 | 0 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: | /messaging | dlx-errors-transform | False | 0 | True | | 2016-02-01 13:59:17 | 13760 | 0 | 0 | 0 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: | /messaging | dlx-load | False | 0 | True | | 2016-02-01 13:59:22 | 13760 | 0 | 0 | 0 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: | /messaging | dlx-sequencer | False | 0 | True | | 2016-02-01 13:59:16 | 13760 | 0 | 0 | 0 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: | /messaging | dlx-transform | False | 0 | True | | 2016-02-01 13:59:21 | 13760 | 0 | 0 | 0 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: | /messaging | errors-load | False | 0 | True | | 2016-02-01 13:59:16 | 13760 | 0 | 0 | 0 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: | /messaging | errors-transform | False | 0 | True | | 2016-02-01 13:59:19 | 13760 | 0 | 0 | 0 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: | /messaging | load-sql | False | 1 | True | | | 47640 | 0 | 0 | 0 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: | /messaging | pond-seq | False | 0 | True | | 2016-02-01 13:59:17 | 13760 | 0 | 0 | 0 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: | /messaging | transform-load-json | False | 1 | True | | | 7629200 | 4701 | 4651 | 50 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: | /messaging | transform-rim | False | 1 | True | | | 68312 | 0 | 0 | 0 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: | /messaging | unrouted | False | 0 | True | | 2016-02-01 13:59:15 | 13760 | 0 | 0 | 0 | rabbit@74efe8c49a9a | | running |
[127.0.0.1] out: +------------+----------------------+-------------+-----------+---------+------------------------+---------------------+---------+----------+----------------+-------------------------+---------------------+--------+---------+
[127.0.0.1] out:
For demonstration purposes it is advised to run the generator for about 10 to 20 seconds, then stop it.
$ sudo /usr/bin/supervisorctl -c /etc/xfm/supervisord/supervisord.conf stop xfm-generator:
Now we will have some actual contents in the database:
$ psql -U xfmuser lake
psql (9.5.0)
Type "help" for help.
lake=# select count(*) from "Patient";
count
-------
225
(1 row)
lake=# select count(*) from "document";
count
-------
9119
(1 row)