Once again I welcome guest blogger Mark Mikofski. Mark has written here last year about JGIT-Matlab integration and earlier this year on JSON-Matlab integration. Today, Mark shows how to use the well-known open-source memcached library for data transfer between separate Matlab processes. Readers are also referred to Mark’s article on his blog. I have already written about various ways to communicate between separate Matlab processes – today’s article is an important complement to these methods.
Downloads
The memcached open-source library is great for sending objects from process to process. It is typically used to cache large data objects from databases or in a distributed environment, but we can also use it as a simple distributed shared memory system, which stores data in key-value pairs (as in a hashtable).
I was able to use memcached to set and retrieve objects from two different instances of Matlab. Both the Java and .NET variants of memcached can be used for this. memcached requires two components: server and client: The server comes precompiled, while the client needs to be compiled by us.
The memcached server was compiled by Trond Norbye from Couchbase (previously Membase and Northscale) for 32-bit and 64-bit Windows OS. See below how to run it as a service using the Python PyWin32 package.
I compiled Windows binaries of memcached-client libraries for both the Java and .NET using Java-1.7 and Visual Studio 2010 and zipped them up here.
Note: additional (non-memcached) shared-memory implementations used in Matlab include Joshua Dillon’s sharedmatrix (also see here), and Kevin Stone’s SharedMemory utilities, which use POSIX shared-memory and the Boost IPC library. Rice University’s TreadMarks library is another example of a shared-memory approach that has been used with Matlab, in the MATmarks package (note that the current availability of MATmarks is unclear).
.NET
We use the Memcached server version 1.4.5 patched for 64-bit Windows, precompiled by Trond Norbye from Couchbase (previously Membase and Northscale).
For the Memcached .NET client, download the Memcached.ClientLibrary
port of com.meetup.memcached
from SourceForge, and then compile using Microsoft Visual Studio 2010 C#, Release/AnyCPU configuration. Since the original project files were for MSVC-8, MSVC-10 starts a conversion wizard that first backed up the previous project files and then creates a new MSVC-10 project, including a new solution file. I then build the clientlib_2.0
project from the MSVC-10 IDE GUI using “build” from the menu, and voila: I got a new DLL.
Usage in Matlab is as follows:
- Start the memcached server:
C:\> C:\path\to\memcached.exe -vv
- Do this on both MATLAB instances:
asm = NET.addAssembly('C:\full\path\to\Memcached.ClientLibrary.dll'); pool = Memcached.ClientLibrary.SockIOPool.GetInstance(); pool.SetServers({'127.0.0.1:11211'}); pool.Initialize; mc = Memcached.ClientLibrary.MemcachedClient();
- On MATLAB instance #1:
mc.Set('name','mark')
- On MATLAB instance #2:
>> myName = mc.Get('name') myName = mark
Java
MATLAB and memcached also works perfectly with the original meetup.com Java version that the .NET version was ported from. The commands are exactly the same, but the Apache logger is not cleaned up for the non-bench/test sources (with isErrorEnabled()
, etc. see jlog4
documentaion), so you always get this error message:
log4j:WARN No appenders could be found for logger (com.meetup.memcached.SockIOPool).
log4j:WARN Please initialize the log4j system properly.
Because there are log calls in the MemcachedClient and SockIOPool files that never have BasicConfiguration.configure()
or set any jlog4.
like the appender
hence the error. Of course they never meant for log messages to be displayed when deployed, so wrapping with isErrorEnabled()
like the .NET version does would be better.
The Java package is called com.meetup.memcached
. We should build it ourselves from the Github source. The jar from the Maven repository didn’t work (attempting to start the sock I/O pool raised several Java errors due to missing includes), and differs a bit from the GitHub repo.
$ /c/Program\ Files/Java/jdk1.7.0_55/bin/javac.exe -verbose -classpath ../lib/log4j.jar -sourcepath com/meetup/memcached/ -source 1.6 -target 1.6 -d ../bin/ com/meetup/memcached/*.java $ /c/Program\ Files/Java/jdk1.7.0_55/bin/jar.exe -cvf MeetupMemcached.jar com/
To use in Matlab, first, start the memcached server, then start sock I/O pools and memcached clients on both Matlab instances:
>> javaaddpath('C:\full\path\to\MeetupMemcached.jar'); >> pool = com.meetup.memcached.SockIOPool.getInstance(); >> pool.setServers({'127.0.0.1:11211'}); >> pool.initialize; >> mc = com.meetup.memcached.MemcachedClient; >> mc.set('name','mark'); % on 1st instance/process >> myName = mc.get('name') % on 2nd instance/process myName = mark
Other clients
- xmemcached – Github:killme2008, Google Code project and Maven repo
- Enyim – NuGet and Github:enyim
I couldn’t get this assembly to load as built, I always got an “Strong Name Validation Failed” error, perhaps because I am on a 64-bit machine, but using MSVC express. - spymemcached – Github:dustin, Google Code project and Maven repo
I also couldn’t get this to work. Even though I could make an array of Java socket objects usingInetSocket
the connection was always refused even though the memcached server was operating on the specified port.
The Xmemcached client works well. It is the most recently updated. There are jar files on the releases page of the GitHub repo. Here is an example from the 2.0.0 release from this April. The example is from the google.code wiki User Guide in English.
>> javaaddpath('C:\full\path\to\xmemcached-2.0.0.jar'); >> addr = net.rubyeye.xmemcached.utils.AddrUtil.getAddresses('localhost:11211') addr = [localhost/127.0.0.1:11211] >> builder = net.rubyeye.xmemcached.XMemcachedClientBuilder(addr) builder = net.rubyeye.xmemcached.XMemcachedClientBuilder@7ef6a26 >> mc = builder.build() log4j:WARN No appenders could be found for logger (net.rubyeye.xmemcached.XMemcachedClient). log4j:WARN Please initialize the log4j system properly. mc = net.rubyeye.xmemcached.XMemcachedClient@275e6ce5 >> mc.set('name',0,'mark') ans = 1 >> myName = mc.get('name') myName = mark
memcached server as Windows service
This Gist uses Python PyWin32 win32service
to install, remove, configure, start and stop the memcached server.
Related posts:
- Serializing/deserializing Matlab data Matlab does not provide a documented manner to serialize data into a byte stream, but we can do this with some undocumented functionality. ...
- Accessing plot brushed data Plot data brushing can be accessed programmatically using very simple pure-Matlab code...
- Draggable plot data-tips Matlab's standard plot data-tips can be customized to enable dragging, without being limitted to be adjacent to their data-point. ...
- Editbox data input validation Undocumented features of Matlab editbox uicontrols enable immediate user-input data validation...