Mercurial > hg > orthanc-book
diff Sphinx/source/faq/scalability.rst @ 643:411e82bb3a9f
documenting revisions and multiple writers
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 23 Apr 2021 15:47:14 +0200 |
parents | 75ac001a48ac |
children | fe7b80fe3caf |
line wrap: on
line diff
--- a/Sphinx/source/faq/scalability.rst Fri Apr 23 10:34:13 2021 +0200 +++ b/Sphinx/source/faq/scalability.rst Fri Apr 23 15:47:14 2021 +0200 @@ -90,6 +90,20 @@ * ``SaveJobs = false`` * ``StorageAccessOnFind = Never`` +* Since Orthanc 1.9.2 and PostgreSQL plugins 4.0: By default, the + PostgreSQL index plugin uses 1 single connection to the PostgreSQL + database. You can have multiple connections by setting the + ``IndexConnectionsCount`` to a higher value (for instance ``5``) in + the ``PostgreSQL`` section of the configuration file. This will + improve concurrency. Check out :ref:`the explanation below <multiple-writers>`. + +* Since Orthanc 1.9.2 and PostgreSQL plugins 4.0: If you have an + hospital-wide VNA deployment, you could consider to deploy multiple + Orthanc servers sharing the same PostgreSQL database. A typical + scenario is having one "writer" Orthanc server that handles the + ingesting of DICOM instances, and multiple "reader" Orthanc servers + with features such as DICOMweb or viewers. + * Make sure to carefully :ref:`read the logs <log>` in ``--verbose`` mode, especially at the startup of Orthanc. The logs may contain very important information regarding performance. @@ -175,7 +189,11 @@ the `manpage <http://man7.org/linux/man-pages/man3/mallopt.3.html>`__ of ``mallopt()`` for more information. -**Status of the Docker images:** +**Status:** + +* Since **Orthanc 1.8.2**, the global configuration ``MallocArenaMax`` + automatically sets ``MALLOC_MMAP_THRESHOLD_`` (defaults to ``5``) + during the startup of Orthanc. * The ``jodogne/orthanc`` and ``jodogne/orthanc-plugins`` Docker images automatically set ``MALLOC_ARENA_MAX`` to ``5`` **since @@ -191,55 +209,134 @@ Known limitations ----------------- -Exclusive access to the DB -^^^^^^^^^^^^^^^^^^^^^^^^^^ +Exclusive access to the DB in Orthanc <= 1.9.1 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Orthanc was originally designed as a mini-DICOM server in 1-to-1 +relation with a SQLite database. Until **Orthanc 1.9.1**, because of +this original design, the internal code accessing the DB was affected +by a strong limitation: Inside a single Orthanc process, there was no +concurrent access to the DB. + +One solution to avoid this limitation was to have multiple Orthanc +accessing the same DB (works only for MySQL and PostgreSQL) as +presented in this `sample +<https://bitbucket.org/osimis/orthanc-setup-samples/src/master/docker/multiple-orthancs-on-same-db/>`__. +However, this solution was only robust if there was **one single +"writer" Orthanc server** (i.e. only one Orthanc was modifying the +database). Indeed, the core of Orthanc <= 1.9.1 did not support the +replay of database transactions, which is necessary to deal with +conflicts between several instances of Orthanc that would +simultaneously write to the database. -As of Orthanc 1.9.1, the internal code accessing the DB is still affected -by limitations induced by the SQLite engine that was the only one originally -available at the beginning of the project: inside a single Orthanc process, -there is no concurrent access to the DB. +Concretely, in Orthanc <= 1.9.1, when connecting multiple Orthanc to a +single database by setting ``Lock`` to ``false``, there should only be +one instance of Orthanc acting as a writer and all the other instances +of Orthanc acting as readers only. Be careful to set the option +``SaveJobs`` to ``false`` in the configuration file of all the +instances of Orthanc acting as readers (otherwise the readers would +also modify the database). -One solution to avoid this limitation is to have multiple Orthanc accessing -the same DB (works only for MySQL and PostgreSQL) as presented in this `sample -<https://bitbucket.org/osimis/orthanc-setup-samples/src/master/docker/multiple-orthancs-on-same-db/>`__. +Some issues reported in our bug tracker are related this limitation: +`issue 83 <https://bugs.orthanc-server.com/show_bug.cgi?id=83>`__, +`issue 121 <https://bugs.orthanc-server.com/show_bug.cgi?id=121>`__, +`issue 151 <https://bugs.orthanc-server.com/show_bug.cgi?id=151>`__. + +This limitation has disappeared with Orthanc 1.9.2 and +PostgreSQL/MySQL plugins 4.0, were the database engine was fully +rewritten. + + +.. _multiple-writers: + +Concurrent accesses to the DB in Orthanc >= 1.9.2 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Also note that the core of Orthanc does not currently support the replay -of database transactions, which is necessary to deal with conflicts -between several instances of Orthanc that would simultaneously write -to the database. As a consequence, as of Orthanc 1.9.1, when connecting multiple -Orthanc to a single database by setting ``Lock`` to ``false``, there -should only be one instance of Orthanc acting as a writer and all the -other instances of Orthanc acting as readers only. Be careful to set -the option ``SaveJobs`` to ``false`` in the configuration file of all -the instances of Orthanc acting as readers. +In **Orthanc 1.9.2 and PostgreSQL/MySQL plugins 4.0**, the database +engine of Orthanc was rewritten from scratch to allow multiple +writers/readers to share the same database. This new feature +necessitated a full refactoring of the database engine, so as to +replay transactions in the case of collisions between concurrent +transactions to the database. + +Furthermore, one Orthanc server can also manage several connections to +PostgreSQL or MySQL, in order to improve performance by adding +concurrency. Read-only database transactions are also distinguished +from read-write transactions in order for the database engine to +further optimize the patterns of access. + +Summarizing, the **multiple readers/writers** is now possible. Here +is a drawing representing a possible deployment: + +.. image:: ../images/2021-04-22-MultipleWriters.png + :align: center + :width: 500px + +Care must be taken to the following aspects: -A refactoring is needed to improve the core of Orthanc in that -respect, for which we are looking for funding from the -industry. Some issues reported in our bug tracker call for this -refactoring: `issue 83 -<https://bugs.orthanc-server.com/show_bug.cgi?id=83>`__, `issue 121 -<https://bugs.orthanc-server.com/show_bug.cgi?id=121>`__, `issue 151 -<https://bugs.orthanc-server.com/show_bug.cgi?id=151>`__. +* Orthanc 1.9.2 must be combined with a database plugin that supports + multiple writers. This is the case of the PostgreSQL and MySQL + plugins with version >= 4.0. The built-in SQLite database **does + not** support multiple writers. + +* Concurrent access can result in so-called `non-serializable + transactions + <https://en.wikipedia.org/wiki/Isolation_(database_systems)#Serializable>`__ + if two separate database transactions modify the database at the + same time (cf. ``ErrorCode_DatabaseCannotSerialize`` in the source + code of Orthanc). Orthanc will **automatically replay such + transactions** a certain number of times (waiting 100ms more between + each retry), until the transactions succeed. The plugins provide an + option to control the maximum number of retries. If the maximum + number of retries is exceeded, the ``503 Service Unavailable`` HTTP + error is raised (server overloaded because of unsuccessful retries + of concurrent transactions). + +* If a higher-level application **modifies metadata and/or + attachments** in the presence of multiple writers, Orthanc provides + a :ref:`revision mechanism <revisions>` to prevent concurrent + updates. + Latency ^^^^^^^ -As of Orthanc 1.9.1, Orthanc still performs quite a large number of small -SQL requests. A simple request to a route like ``/studies/{id}`` can trigger -6 SQL queries. +For some queries to the database, Orthanc performs several small SQL +requests. For instance, a request to a route like ``/studies/{id}`` +can trigger 6 SQL queries. Given these round-trips between Orthanc and +the DB server, it's important for the **network latency to be as small +as possible**. For instance, if your latency is 20ms, a single request +to ``/studies/{id}`` might take 120ms. Typically, a latency of 1-4 ms +is expected to have correct performances. -This is not an ideal situation and this might be addressed -in a future larger DB refactoring (the most time-consuming queries have already -been optimized). Given the large number of round-trips -between Orthanc and the DB server, it's important that the latency is reduced -as much as possible. I.e, if deploying Orthanc in a cloud infrastructure, -make sure that the DB server and Orthanc VMs are located in the same datacenter. +As a consequence, if deploying Orthanc in a cloud infrastructure, make +sure that the DB server and Orthanc VMs are located in the **same +datacenter**. Note that most of the time-consuming queries have +already been optimized, and that future versions of Orthanc SDK might +aggregate even more SQL requests. -Typically, a latency of 1-4 ms is expected to have correct performances. If your -latency is 20ms, a simple request to ``/studies/{id}`` might spend 120ms in -round-trip alone. +Starting with Orthanc 1.9.2, and PostgreSQL/MySQL index plugins 4.0, +Orthanc can also be configured to handle **multiple connections to the +database server** by setting the ``IndexConnectionsCount`` to a value +greater than ``1``. This allows concurrent accesses to the database, +which avoids to sequentially wait for a database transaction to be +concluded before starting another one. Having multiple connections +makes the latency problem much less important. +Slow deletions +^^^^^^^^^^^^^^ +Deleting large studies can take some time, because removing a large +number of files from a filesystem can be an expensive operation (which +might sound counterintuitive). +It is possible to create an :ref:`storage area plugin +<creating-plugins>` that delays the actual deletion from the +filesystem. The plugin would maintain a queue (e.g. as a SQLite +database) of files to be removed. The actual deletion from the +filesystem would be done asynchronously in a separate thread. + +We are looking for funding from the industry to implement such a +plugin.