项目上有一个性能优化的需求,需要进一步优化远程调用Redis导致的RT偏高问题,目前的想法是做两级缓存,通过加入一个基于嵌入式数据库引擎的本地缓存,来降低对远端redis的依赖;大致的结构如下:
业务服务 —> 本地数据库引擎 -> 远端redis
之所以用数据库引擎,是因为在满足QPS的情况下,想尽可能本地化更多的数据,直接用内存太奢侈了。
对于读操作:优先读取本地,本地没有的话,再读区远端redis,远端的值会写回到本地
对于写操作:直接写本地,然后后台线程异步同步至远端,其中业务逻辑可以容忍短时的数据不一致情况。
WiredTiger是mongodb收购过来的一个存储引擎,从2.3版本之后,便是mongodb的默认引擎。
除了WiredTiger之外,一些本地的嵌入式数据库引擎还有:地址
相比Google的LevelDb引擎的性能对比:链接
本文主要记录WiredTiger安装的流程,以及一个简单的Java操作示例,安装的环境:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $system_profiler SPSoftwareDataType Software: System Software Overview: System Version: macOS 10.14.6 (18G48f) Kernel Version: Darwin 18.7.0 Boot Volume: Untitled Boot Mode: Normal Computer Name: yuanke’s MacBook Ali User Name: yuanke wei (yuankewei) Secure Virtual Memory: Enabled System Integrity Protection: Enabled Time since boot: 17 days 5:20
(1)git下载相关的代码,并切换到稳定分支
1 2 3 4 5 $git clone git://github.com/wiredtiger/wiredtiger.git $cd wiredtiger/ $git checkout -b mongodb-4.4 origin/mongodb-4.4
(2)安装相关编译工具
1 2 #采用brew安装 $brew install autoconf automake libtool swig
(3)开始编译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 $./autogen.sh #mac下查看JAVA_HOME的命令为: $/usr/libexec/java_home #**编辑生成的configure文件, 17620行开始,替换 case "$host_os" in darwin*) _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[^/]*$::'` _JINC="$_JTOPDIR/Headers";; *) _JINC="$_JTOPDIR/include";; esac 为 case "$host_os" in *) _JINC="$_JTOPDIR/include";; esac $./configure --enable-java --enable-python #开始编译 $make #安装相关库文件到/usr/local/ $make install
(4)采用idea建立一个maven工程
1 2 3 4 5 6 7 8 9 10 #wiredtiger安装之后,java的jar包和jni本地库的位置为: $ls /usr/local/share/java/wiredtiger-3.2.0/ libwiredtiger_java.0.dylib libwiredtiger_java.dylib wiredtiger.jar libwiredtiger_java.a libwiredtiger_java.la 编辑idea的工程,引入对应的jar包 Project Settings -> Libraries 另外,运行测试程序时,还需要加入jni本地库的路径,idea的jvm运行参数重加入: -Djava.library.path=/usr/local/share/java/wiredtiger-3.2.0
完整的测试程序如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 import com.wiredtiger.db.*; public class Main { public static void main(String[] args) { Connection conn; Session s; Cursor c; try { //保证目录是存在的/Users/yuankewei/temp/WT_HOME conn = wiredtiger.open("/Users/yuankewei/temp/WT_HOME", "create"); s = conn.open_session(null); } catch (WiredTigerException wte) { System.err.println("WiredTigerException: " + wte); return; } /*! [access example connection] */ try { /*! [access example table create] */ //创建了一个table,key是一个String,Value也是一个String s.create("table:t", "key_format=S,value_format=S"); /*! [access example table create] */ /*! [access example cursor open] */ c = s.open_cursor("table:t", null, null); /*! [access example cursor open] */ } catch (WiredTigerException wte) { System.err.println("WiredTigerException: " + wte); return; } /*! [access example cursor insert] */ //插入一个数据 try { c.putKeyString("foo"); c.putValueString("bar"); c.insert(); } catch (WiredTigerPackingException wtpe) { System.err.println("WiredTigerPackingException: " + wtpe); } catch (WiredTigerException wte) { System.err.println("WiredTigerException: " + wte); } /*! [access example cursor insert] */ //再插入一行数据 try { c.putKeyString("foo1"); c.putValueByteArray("bar1".getBytes()); c.insert(); } catch (WiredTigerPackingException wtpe) { System.err.println("WiredTigerPackingException: " + wtpe); } catch (WiredTigerException wte) { System.err.println("WiredTigerException: " + wte); } //根据key查询value try { c.reset(); c.putKeyString("foo1"); c.search(); System.out.println(c.getValueString()); } catch (Exception e) { } /*! [access example cursor insert] */ /*! [access example cursor list] */ //遍历数据 try { c.reset(); while (c.next() == 0) { System.out.println("Got: " + c.getKeyString() + ", " + new String(c.getValueByteArray())); } } catch (WiredTigerPackingException wtpe) { System.err.println("WiredTigerPackingException: " + wtpe); } catch (WiredTigerException wte) { System.err.println("WiredTigerException: " + wte); } } }
程序的数据为:
1 2 3 bar1 Got: foo, bar Got: foo1, bar1