Jeff Li

Be another Jeff

Getting Started with RocksDB in CentOS 7

Introduction

RocksDB is a high performance embedded key value storage engine which is written in C++. Though its name tells that it is a database, it is actually a C++ library providing a bunch of API instead of a Client-Server architected database.

I am not a C++ programmer and when trying to play with RocksDB following the Getting Started guide from the RocksDB website, I found it is not easy to run the example in CentOS 7 with either dynamic or static linkage. To be more specific with dynamic linkage, the search paths of dynamic libraries vary from Linux distributions but the installation script of RocksDB does not take care of that.

This post is intended for those who want to play with RocksDB but failed to run the example. What will be mentioned including

  • How to install RocksDB as dynamic library from source in CentOS 7
  • How to install RocksDB as static library in CentOS 7
  • How to run the example program

Here is the demo program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include "rocksdb/db.h"

using namespace std;

int main() {
    rocksdb::DB* db;
    rocksdb::Options options;
    options.create_if_missing = true;
    rocksdb::Status status = rocksdb::DB::Open(options, "/tmp/kv", &db);

    delete db;

    return 0;
}

Before you continue, please install the dependencies.

1
sudo yum install gflags-devel snappy-devel zlib-devel bzip2-devel  gcc-c++  libstdc++-devel -y

Dynamic Linkage

Install the shared lib

First, run the command line to build dynamic library

1
DEBUG_LEVEL=0 make shared_lib

The Makefile provides a target called install-shared to install RocksDB shared lib.

1
DEBUG_LEVEL=0 sudo -E make install-shared

The target actually includes two jobs:

  1. Copy all the header files under $SRC_ROOT/include/rocksdb to /usr/local/include/rocksdb
  2. Copy the .so file and symbolic links to /usr/local/lib

Run the example

  • Compile the program with following command
1
g++ -o demo -std=c++11 -lrocksdb demo.cpp
  • Run the program with ./demo and an error occurs
1
./demo: error while loading shared libraries: librocksdb.so.4.9: cannot open shared object file: No such file or directory

The problem with the install-shared target is that /usr/local/lib is in g++’s dynamic library search paths but not in ldconfig’s in CentOS 7 by default. So the program can be built during compiling time but will cause dynamic library load error during run time. This can be verified by following commands:

  • Show search paths of g++
1
ld --verbose | grep SEARCH_DIR | tr -s ' ;' \\012
  • Show search paths of ldconfig
1
ldconfig -v 2>/dev/null | grep -v ^$'\t'

There are 2 ways to resolve the issue. And EITHER one is ok.

  • Installing .so file and symbolic links into both the search paths of g++ and ldconfig
1
2
INSTALL_PATH=/usr sudo -E make install-shared
sudo ldconfig -v  #refresh the ldconfig cache
  • Add /usr/local/lib to the ldconfig’s search paths.
1
2
echo "/usr/local/lib" |sudo tee /etc/ld.so.conf.d/rocksdb-x86_64.conf
sudo ldconfig -v  #refresh the ldconfig cache

Static Linkage

As mentioned before, /usr/local/lib is in g++’s search path, thus there is no such dynamic load issue with static RocksDB. First build and install static RocksDB.

1
2
DEBUG_LEVEL=0 make static_lib
DEBUG_LEVEL=0 sudo -E make install-static

Then compile the demo program with

1
g++  demo.cc -o demo -lpthread -lrocksdb  -std=c++11  -lsnappy  -lz -lbz2

or simply

1
g++  demo.cc -o demo -lpthread -lrocksdb  -std=c++11

Don’t miss the pthread lib.

Conclusion

The problem is caused by shared library search paths which could vary from different Linux distributions. A good solution to avoid the issue is packaging the files into a rpm package, and deb package in Debian platform of course.

It is worth noting that /usr/lib64, instead of /usr/lib, is the common place to hold the lib files in x86_64 RedHat family OSes such as CentOS, Fedora. Though /usr/lib works but /usr/lib64 is a better place for the lib files in RedHat family. There is a patch to take care of that when creating a RPM.

There is another problem I have not figured out yet. It is about static linkage. If anyone know how to link RocksDB program statically please drop me a note.

Comments