RocksDB Java基本操作、乐观锁、事务及性能测试
RocksDB
rocksdb是一款由Facebook使用C/C++开发的嵌入式的持久化的KV数据库
基于Google的LevelDB改进而来,redis是基于内存的会存在丢失情况,而RocksDB不会丢失且性能极好(硬盘和SSD)。
属于单机数据库,且同一库只可被一个进程读取写入。(线程安全需要用事务)
适用场景
1.对写性能要求很高,同时有较大内存来缓存SST块以提供快速读的场景;
2.SSD等对写放大比较敏感以及磁盘等对随机写比较敏感的场景;
3.需要变长kv存储的场景;
4.小规模元数据的存取;
不适合场景
1.大value的场景,需要做kv分离;
2.大规模数据的存取
-
项目环境 maven jdk1.8 windows10
-
项目类型 maven项目
-
依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.54</version> </dependency> <dependency> <groupId>org.kevoree.mwg.plugins</groupId> <artifactId>rocksdb</artifactId> <version>6</version> </dependency> <dependency> <groupId>org.rocksdb</groupId> <artifactId>rocksdbjni</artifactId> <version>6.6.4</version> </dependency>
-
还需要手动下载一个jar包引入
rockssdb-6.jar
https://www.mvnjar.com/org.kevoree.mwg.plugins/rocksdb/6/detail.html
-
-
基本操作示范类
步骤
建立连接
调用get put delete close方法即可
import org.rocksdb.Options; import org.rocksdb.RocksDB; import org.rocksdb.RocksDBException; /** * RocksDB基本操作类 * 由于默认操作要传入的是bytes所以做了一层封装,直接传入string操作。 */ public class RocksDBOps { //数据库路径(文件夹) private String path; //rocksdb连接 private RocksDB rocksDB; static { //加载库 RocksDB.loadLibrary(); } public RocksDBOps(String path) throws RocksDBException { this.path=path; rocksDB=RocksDB.open(path); } /** * 写入数据 * @param key 键 * @param value 值 * @return boolean 成功与否 */ public boolean put(String key,String value){ try { rocksDB.put(key.getBytes(),value.getBytes()); return true; }catch (RocksDBException e){ return false; } } /** * 获取数据 * @param key 键 * @return string 值 */ public String get(String key){ try { byte[] bytes=rocksDB.get(key.getBytes()); if(bytes!=null){ return new String(bytes); } }catch (RocksDBException e){ e.printStackTrace(); } return null; } /** * 删除数据 * @param key 键 * @return boolean 成功与否 */ public boolean delete(String key){ try { rocksDB.delete(key.getBytes()); return true; }catch (RocksDBException e){ e.printStackTrace(); } return false; } /** * 关闭连接 */ public void close(){ if(rocksDB!=null){ rocksDB.close(); } } public static void main(String[] args) { String path="C:\\rocksdb_test.db"; try { //创建连接 RocksDBOps rocksDBOps=new RocksDBOps(path); String key="chen"; //写入 rocksDBOps.put(key,"programmer"); //获取 String job=rocksDBOps.get(key); System.out.println("job:"+job); //删除 boolean ret=rocksDBOps.delete(key); if(ret){ System.out.println("deleted"); }else { System.err.println("delete failed"); } //关闭连接 rocksDBOps.close(); }catch (Exception e){ e.printStackTrace(); } } }
-
乐观事务操作
操作步骤
建立连接,创建事务,对事务操作,提交事务,失败时回滚,最终关闭
写同一个两个事务只成功一个。
import org.rocksdb.*; public class OptimisticTransactionTest { private static OptimisticTransactionDB db; private static final String path="C:\\rocksdb_test.db"; private static final String key="test"; static { try { //加载库 RocksDB.loadLibrary(); //创建连接 db= OptimisticTransactionDB.open(new Options().setCreateIfMissing(true),path); //设置初始值(由于多次运行该程序测试,做一个初始化操作) db.put(key.getBytes(),"C".getBytes()); }catch (Exception e){ e.printStackTrace(); } } /** * 修改某个key的乐观锁测试 */ public class TestThread extends Thread{ private String name; private int sleep; public TestThread(String name,int sleep){ super(name); this.name=name; this.sleep=sleep; } @Override public void run() { Transaction transaction=db.beginTransaction(new WriteOptions()); try { transaction.put(key.getBytes(),name.getBytes()); // Thread.sleep(sleep); transaction.commit(); System.out.println(name+" success"); }catch (Exception e){ System.err.println(name+" failed"); try { transaction.rollback(); }catch (Exception e1){ e1.printStackTrace(); } e.printStackTrace(); } } } public void test(){ TestThread t1=new TestThread("A",500); TestThread t2=new TestThread("B",1000); t1.start(); t2.start(); } public static void main(String[] args) { new OptimisticTransactionTest().test(); } }
-
读写测速(不考虑线程安全情况)
测试类
package bean; import com.alibaba.fastjson.JSONObject; import java.math.BigDecimal; import java.util.Random; public class User { private Long uid; private String username; private String password; private Integer age; private BigDecimal balance; public Long getUid() { return uid; } public void setUid(Long uid) { this.uid = uid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public BigDecimal getBalance() { return balance; } public void setBalance(BigDecimal balance) { this.balance = balance; } @Override public String toString() { return JSONObject.toJSONString(this); } public static User randomUser(){ Random random=new Random(); int n=random.nextInt(10); User user=new User(); user.setUid(123004545L*n); user.setAge(n); user.setBalance(new BigDecimal(n*1000000)); user.setPassword("123123"+n); user.setUsername("hello"+n); return user; } }
机器:i5 9500 @ 3.00GHz 6核心 16GB内存 windows (还开着挺多开发软件,但是这个单进程读写应该不会受到太多影响)
测试50万次读取写入带有5个不同类型的实例
bean概貌:
public class User { private Long uid; private String username; private String password; private Integer age; private BigDecimal balance; }
结果:
读取 50万次/秒
写入 10万次/秒
测试3000万次读取写入带有5个不同类型的实例
结果:
读取26.万次/秒
写入12万次/秒
-
性能测试(使用乐观锁的事务)
六核机器
单线程写入3万次每秒(数据量少就更快)
双线程写入4万次
四线程写入5万次
六线程写入5万次
十二线程写入4.5万次
-
性能测试结论:建议使用与核心数相同的线程来操作RocksDB可发挥最优性能
本文来自博客园,作者:HumorChen99,转载请注明原文链接:https://www.cnblogs.com/HumorChen/p/18039681
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~