I am often asked how we store information in Alfresco and how we made the choices we made for storage. Content storage in the Alfresco ECM system is generally hidden from both the user and applications. This provides us with the flexibility to store content in different storage mediums, different locations and in secondary and tertiary storage without affecting the application or user experience. This is true for most ECM systems.
When originally architecting the Alfresco system, we needed to choose an initial storage mechanism and chose to store content as ordinary files in the file system. There were a number of reasons for doing so:
- Our support for the CIFS protocol (also known as SMB) that allows the system to emulate a Microsoft Shared File system requires us to conform to the idiosyncrasies of that protocol. The CIFS protocol is asynchronous, non-transactional and requires random access. Trying to support this protocol on top of a database BLOB would require constant fetching of an entire document from the database and continually save the entire document providing unacceptable performance.
- Most database systems are not optimized to handle large amounts of information in large BLOBs (Binary Large Objects) or CLOBs (Character Large Object), even if they support these objects. There is a tendency for these objects to clutter the cache of the database and thus detract from the performance of the overall system that requires quick access to metadata.
- Real-time streaming of large content such as video and audio is considerably simpler using files. Using a file allows us to open a direct stream from the file to the application for zero latency on start of the stream. Storing this information in the database would force us to make copies of the information before serving up the content stream.
- File system caching is extremely efficient and has the advantage of having a high priority in the operating system. This allows the Alfresco system to serve up content as URLs with an extremely fast access time that is measured in microseconds rather than milliseconds.
We considered other means of storing the content, including storing information as BLOBs in the database, primarily due to the simplicity of backup and database distribution. However, just like any other ECM system, we maintain a full-text index outside of the database, which would also need to be backed up and replicated. In fact, the Oracle Content Management System also stores fulltext indexes outside of the database. Therefore, we felt it was more appropriate to address the backup, replication and recovery issues directly rather than just relying on the database.
Our primary choice for backup and recovery was to use master-slave hot standby configuration. We chose this because of low latency of recovery and simplicity of management. The Alfresco system manages the replication of metadata using the underlying database replication mechanism, replication of files using shared drives and rsync, and synchronization of indexes using transactional information transferred through the database replication.
Hot backup can still be done for single systems using a mechanism very similar to systems such as Documentum. Because of the fact that content is updated sequentially and old versions of content are only removed as part of a garbage collecting process, it is possible to back up a running Alfresco system. The steps required to do this are:
- Suspend any file deletions or prevent clean-up
- Back up the database first using the appropriate hot backup tool for the database
- Back up the fulltext index next
- Back up the file system - there may be newer files that will be ignored on restore, but any files deleted after database backup will still be available
Restoration in reverse order will recover the system back to the state that it was in at the point of the hot backup.
The Alfresco system will add new types of storage mechanisms in the future to support different application requirements. There are already different types of storage in the Alfresco system for storing older versions, archives and recoverable deleted items. Future storage types include:
- Database BLOB and VARCHAR - Although it may not be possible to use the CIFS interface against this storage type, a flexible model that can choose between BLOB and VARCHAR based upon size is useful for a high-performance XML storage system
- Distributed - A replicated store of information that is accessed from remote geographic locations can have local copies of information for low-latency access of information that may originated in a trans-continental environment
- Foreign Storage - Allow the Alfresco system to manage and index information that may be managed or stored by another system
- Off-line Storage - Automated storage and retrieval of archival information is important for records management applications
- Encrypted - It is possible to provide an encrypted store of document information using the native CIFS encryption capability. However, it is useful for the storage mechanism to support encryption to hide non-CIFS information from system administration staff.
- Versioned Storage - Using a mechanism similar to source code control system, store only changes between versions
"The CIFS protocol is asynchronous, non-transactional and requires random access. Trying to support this protocol on top of a database BLOB would require constant fetching of an entire document from the database and continually save the entire document providing unacceptable performance."
Sorry but this sentence is wrong, it is perfectly possible to have random access to a Blob field in a database and to stream content for it without having to keep any transaction opened. We have done it in several projects and have exactly the same advantages you mention.
Blob specification in java already provides the following methods:
byte[] getBytes(long pos, int length)
int setBytes(long pos, byte[] bytes)
int setBytes(long pos, byte[] bytes, int offset, int len)
With this three methods is pretty simple to extend java.io.InputStream, java.io.OutputStream and RandomAccessFile so that you are able to access a Blob as if it is a simply filesystem file.
As for the transaction need, it is as simple as creating a buffered version that whenever it needs new data simply opens a new transaction, reads a chunk of data into the buffer and closes the transaction, all hidden by the stream implementation. In this way it is easy to stream files in and out a database blob without having to keep a resource as expensive as a transaction.
Posted by: Sergio Berna | 2007.04.12 at 11:01 AM
G'day John,
I understand that clustering Alfresco involves clustering just the application (JVM) and then configuring all nodes to share a single filesystem, thereby requiring that that filesystem be hosted on a SAN / NFS / SMB share.
Does this place any practical limits on how far Alfresco can be clustered before file I/O over the network becomes a bottleneck?
Cheers,
Peter
Posted by: Peter Monks | 2006.09.08 at 05:09 PM