The FHIR Storage (Relational) module is responsible for resource storage and retrieval. It stores data in two places:
To create a new FHIR Storage (Relational) module, you should first ensure that your host server (or virtual machine, docker container, etc.) has access to a dedicated directory with a sufficiently large amount of storage to keep its data.
This directory can be a mounted filesystem or a directory on a local disk but it should be dedicated to the given node. In other words, if this directory is network mounted, it should not be shared across multiple nodes of the cluster.
You will also require a relational database with a user and schema created. See the Platform Requirements page for information on supported database platforms.
When creating a FHIR Storage (Relational) module, you must first choose which version of FHIR it will support. There are multiple types of FHIR Storage (Relational) modules, and each one supports a specific version of FHIR.
In a basic deployment, a single Node with a FHIR Storage (RDBMS) module can be created. This module will service all FHIR requests. This architecture can easily be scaled hirozontally by creating multiple processes for this node.
In more complex architectures, it is possible to create multiple modules (generally on separate nodes) that share the same RDBMS connection details (i.e. the same connection URL). This is typically done when there is a separation of duties needed. This type of architecture is possible in Smile CDR as long as the considerations here are noted.
The FHIR Storage (RDBMS) module has a number of scheduled tasks that can selectively be enabled or disabled.
In most deployments there is no benefit to disabling these tasks, as they do not add any meaningful load to the system unless they detect work that needs doing. The exception to this rule is in deployments where you have multiple Smile CDR Nodes sharing a single relational database schema instance for FHIR Resource storage; in which case, one should enable the Suppress Scheduled Maintenance Jobs property on all but one of such FHIR Storage modules.
Descriptions of the available settings to enable and disable these tasks can be found at Storage Module Scheduled Tasks.
If you wish to take advantage of native RDBMS database replication which creates read-only replicas, you will need to configure the read-only FHIR Storage module with Read-Only Mode Enabled. In this mode, the job scheduler is disabled entirely.
The following diagram shows a Smile CDR cluster with a writeable node and a read-only node using database replication. In this diagram, each of the nodes can be scaled independently, using as many node processes as needed. The Read-Only Mode Enabled setting should be enabled on the read-only node.
When using a node in read-only mode, it is still required to have a non-read-only node as well with at least one process active, even if this node is not actually serving FHIR client requests. This node is required in order to ensure that scheduled background jobs are executed.
Note that this setting will not prevent the server from attempting write transactions in response to FHIR operations such as create and update. This setting is intended to indicate to Smile CDR that connections to the RDBMS will always be read-only, it is not intended to enforce read-only behavior on a writeable database. If you need to ensure that write requests (e.g. FHIR create, update, etc.) are directed to the appropriate node processes, the FHIR Gateway module can be a useful component in your architecture.
By default, the FHIR Storage (Relational) module uses a database LOB column to store resource body text in a separate storage area. See the
RES_TEXT column on the
HFJ_RES_VER table in the HAPI FHIR Database Schema for more information.
This storage mode allows for resources of unlimited size, limited only by available memory. Data is compressed using the GZip compression algorithm in order to reduce storage requirements as well.
Although this form of storage is good for reducing overall storage size, it is not the most efficient in terms of read/write performance. If faster performance is desired, the Inline Resource Storage Below Size (chars) setting can be used to specify that resources under a given size should be stored as regular uncompressed text in a VARCHAR2 column called
RES_TEXT_VC on the
This column is sized by default to a maximum length 4000 characters, so a value of 4000 is a sensible setting. This length is chosen because it is the maximum VARCHAR2 column length on Oracle RDBMS by default. It is possible and acceptable to manually increase the length of this column in your database, in which case you can choose a larger length for this column. Doing so may further improve performance.
For example, if you wish to inline any resources with a length below a length of 10000 characters (this has been found to be an optimal setting in many tests):
HFJ_RES_VERso that it has a maximum length of 10000.
Response: Generally speaking, the only real limitation is for fields that you want to index for searching. So for example, the length of
Observation.note is effectively unbounded. The full resource body is temporarily stored in memory, so there are practical scalability limits if you had massive strings (ie multiple megabytes) and lots of concurrency, but other than that there is no limit.
However, in the case of fields that are indexed for searching the indexer may impose a maximum length on the field. For example,
Patient.name.family will be indexed because it has a search parameter by default. The maximum length for string indexes is 200 characters.
Once you have selected your module type, the first set of configuration options will be the relational database configuration itself. A complete reference of options is found on the Database configuration page.
Most importantly, you will need to configure the following properties:
The Lucene FullText configuration sets up the local filesystem to use for indexing. A complete reference of options is found on the Lucene FullText Indexing configuration page.
Most importantly, you should configure the following property:
The configuration options available for this module type are as follows: