热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

flinkRocksDB介绍以及Flink对RocksDB的支持

篇首语:本文由编程笔记#小编为大家整理,主要介绍了flinkRocksDB介绍以及Flink对RocksDB的支持相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了flinkRocksDB介绍以及Flink对RocksDB的支持相关的知识,希望对你有一定的参考价值。







1.概述

转载:「Flink」RocksDB介绍以及Flink对RocksDB的支持


2.RocksDB简介

RocksDB是基于C++语言编写的嵌入式KV存储引擎,它不是一个分布式的DB,而是一个高效、高性能、单点的数据库引擎。它是由Facebook基于Google开源的kv存储LevelDB开发开发。RocksDB使用LSM存储引擎。它针对不同的生产环境进行调优,可以直接使用内存、也可以使用Flash、或者用硬盘或者HDFS。而且支持不同的压缩算法,有一整套的工具用于生产、调试使用。RocksDB是一种嵌入式、KV型、持久化的存储。

使用嵌入式的数据存储原因有很多,当数据频繁访问内存、或者存储时,网络延迟会增加响应时间。


3.RocksDB的主要应用场景
  • 适应于多CPU场景


    • 一般的商业服务器有很多的CPU核,例如:志强E5系列 - 6核
    • RocksDB可以高效运行在多核服务器上
  • 它提供的RocksDB语义比传统DBMS更简单

  • 高效利用存储


    • RocksDB可以在快速存储上高效运行且不会成为性能瓶颈
    • RocksDB采用LSM引擎,对比B-Tree引擎,它有更好的压缩和更小的写放大
  • 弹性架构,支持扩展

  • 支持IO-bound、in-memory、write-once


4.入门案例

为了简单说明RocksDB,我们这里使用RocksDB的Java版本来编写。

导入Maven依赖

<dependencies>
<!-- https://mvnrepository.com/artifact/org.rocksdb/rocksdbjni -->
<dependency>
<groupId>org.rocksdb</groupId>
<artifactId>rocksdbjni</artifactId>
<version>5.11.3</version>
</dependency>
</dependencies>

基于RocksDB读写数据

public class GettingStartDemo
// 因为RocksDB是由C&#43;&#43;编写的&#xff0c;在Java中使用首先需要加载Native库
static
// Loads the necessary library files.
// Calling this method twice will have no effect.
// By default the method extracts the shared library for loading at
// java.io.tmpdir, however, you can override this temporary location by
// setting the environment variable ROCKSDB_SHAREDLIB_DIR.
// 默认这个方法会加压一个共享库到java.io.tmpdir
RocksDB.loadLibrary();

public static void main(String[] args) throws RocksDBException
// 1. 打开数据库
// 1.1 创建数据库配置
Options dbOpt &#61; new Options();
// 1.2 配置当数据库不存在时自动创建
dbOpt.setCreateIfMissing(true);
// 1.3 打开数据库。因为RocksDB默认是保存在本地磁盘&#xff0c;所以需要指定位置
RocksDB rdb &#61; RocksDB.open(dbOpt, "./data/rocksdb");
// 2. 写入数据
// 2.1 RocksDB都是以字节流的方式写入数据库中&#xff0c;所以我们需要将字符串转换为字节流再写入。这点类似于HBase
byte[] key &#61; "zhangsan".getBytes();
byte[] value &#61; "20".getBytes();
// 2.2 调用put方法写入数据
rdb.put(key, value);
System.out.println("写入数据到RocksDB完成&#xff01;");
// 3. 调用delete方法读取数据
System.out.println("从RocksDB读取key &#61; " &#43; new String(key) &#43; "的value为" &#43; new String(rdb.get(key)));
// 4. 移除数据
rdb.delete(key);
// 关闭资源
rdb.close();
dbOpt.close();


运行程序后&#xff0c;我们可以发现&#xff0c;在data/rocksdb文件夹中&#xff0c;生成了一下几个文件&#xff1a;

- 0000004.sst
sst是RocksDB的数据存储文件&#xff0c;是二进制格式的
0000006.log
log是预写日志文件&#xff0c;LSM架构引擎都是有预写日志的
CURRENT
CURRENT文件是一个文本文件&#xff0c;记录最近的MANIFEST
IDENTITY
存放当前rocksdb的唯一标识
LOCK
LOCK 进程的全局锁&#xff0c;DB一旦被open, 其他进程将无法修改
LOG
rocksdb的操作日志文件&#xff0c; 可配置定期的统计信息写入LOG. 可通过info_log_level调整日志输出级别; 通过keep_log_file_num限制文件数量 等等。
LOG.old.15807.
MANIFECT-000005
记录rocksdb最近的状态变化日志。其中包含manifest日志 和最新的文件指针
OPTIONS-000005
rocksdb的配置文件
OPTIONS-000008

5.Flink使用RocksDBBackend

导入Maven依赖

<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-statebackend-rocksdb_2.11</artifactId>
<version>1.9.0</version>
</dependency>

2、配置启用RocksDBBackend

// 此处也可以是HDFS路径&#xff0c;这里为了测试方便&#xff0c;所以使用的是本地路径
env.setStateBackend(new RocksDBStateBackend("file:///D:/project/java8/data/rocksdb", true));


6.Flink基于RocksDB的增量检查点机制

为什么只有RocksDB状态后端支持增量检查点呢&#xff1f;这是由RocksDB本身的特性决定的。RocksDB是一个基于日志结构合并树&#xff08;LSM树&#xff09;的键值式存储引擎&#xff0c;我们能明确地感觉到&#xff0c;它与HBase肯定有诸多相似之处。如果看官不了解LSM树的话&#xff0c;可以通过这篇文章来做个简单的了解。

在RocksDB中&#xff0c;扮演HBase MemStore角色的写缓存叫做memtable。memtable写满之后也会flush到磁盘&#xff0c;形成与HFile类似的东西&#xff0c;叫做sstable&#xff08;是“有序序列表”即sorted sequence table的缩写&#xff09;。RocksDB也存在compaction线程&#xff0c;在后台合并已经写入的sstable&#xff0c;原有的sstable会包含所有的键值对&#xff0c;合并前的sstable在此后会被删除。

由于Flink检查点生成的时间必须确定&#xff0c;因此不能等待RocksDB的memtable自动flush到磁盘&#xff0c;而是由Flink主动调用RocksDB提供的API强制刷写。有了上面的铺垫&#xff0c;下面通过例子来解释增量检查点的过程。


From https://flink.apache.org/features/2018/01/30/incremental-checkpointing.html

上图示出一个有状态的算子的4个检查点&#xff0c;其ID为2&#xff0c;并且state.checkpoints.num-retained参数设为2&#xff0c;表示保留2个检查点。表格中的4列分别表示RocksDB中的sstable文件&#xff0c;sstable文件与存储系统中文件路径的映射&#xff0c;sstable文件的引用计数&#xff0c;以及保留的检查点的范围。

下面按部就班地解释一下&#xff1a;


  • 检查点CP 1完成后&#xff0c;产生了两个sstable文件&#xff0c;即sstable-(1)与sstable-(2)。这两个文件会写到持久化存储&#xff08;如HDFS&#xff09;&#xff0c;并将它们的引用计数记为1。
  • 检查点CP 2完成后&#xff0c;新增了两个sstable文件&#xff0c;即sstable-(3)与sstable-(4)&#xff0c;这两个文件的引用计数记为1。并且由于我们要保留2个检查点&#xff0c;所以上一步CP 1产生的两个文件也要算在CP 2内&#xff0c;故sstable-(1)与sstable-(2)的引用计数会加1&#xff0c;变成2
  • 检查点CP 3完成后&#xff0c;RocksDB的compaction线程将sstable-(1)、sstable-(2)、sstable-(3)三个文件合并成了一个文件sstable-(1,2,3)。CP 2产生的sstable-(4)得以保留&#xff0c;引用计数变为2&#xff0c;并且又产生了新的sstable-(5)文件。注意此时CP 1已经过期&#xff0c;所以sstable-(1)、sstable-(2)两个文件不会再被引用&#xff0c;引用计数减1
  • 检查点CP 4完成后&#xff0c;RocksDB的compaction线程将sstable-(4)、sstable-(5)以及新生成的sstable-(6)三个文件合并成了sstable-(4,5,6)&#xff0c;并对sstable-(1,2,3)、sstable-(4,5,6)引用加1。由于CP 2也过期了&#xff0c;所以sstable-([1~4])四个文件的引用计数同时减1&#xff0c;这就造成sstable-(1)、sstable-(2)、sstable-(3)的引用计数变为0&#xff0c;Flink就从存储系统中删除掉这三个文件。

通过上面的分析&#xff0c;我们可以看出Flink增量检查点机制的巧妙之处&#xff1a;


  • 通过跟踪sstable的新增和删除&#xff0c;可以记录状态数据的变化&#xff1b;
  • 通过引用计数的方式&#xff0c;上一个检查点中已经存在的文件可以直接被引用&#xff0c;不被引用的文件可以及时删除&#xff1b;
  • 可以保证当前有效的检查点都不引用已经删除的文件&#xff0c;从而保留state.checkpoints.num-retained参数指定的状态历史。

增量检查点解决了大状态checkpointing的问题&#xff0c;但是在从检查点恢复现场时会带来潜在的overhead。这是显然的&#xff1a;当程序出问题后&#xff0c;TaskManager需要从多个检查点中加载状态数据&#xff0c;并且这些数据中还可能会包含将被删除的状态还有一点&#xff0c;就算磁盘空间紧张&#xff0c;旧检查点的文件也不能随便删除&#xff0c;因为新检查点仍然会引用它们&#xff0c;如果贸然删除&#xff0c;程序就无法恢复现场了。可见&#xff0c;优秀的技术方案往往也不是十全十美&#xff0c;往往都是要考虑tradeoff的。


M.参考文献&#xff1a;

RocksDB中文网&#xff1a;https://rocksdb.org.cn/

https://rocksdb.org.cn/doc/RocksJava-Basics.html

https://www.jianshu.com/p/2638e2b379c3

https://www.jianshu.com/p/3302be5542c7







推荐阅读
  • NoSQL数据库,即非关系型数据库,有时也被称作Not Only SQL,是一种区别于传统关系型数据库的管理系统。这类数据库设计用于处理大规模、高并发的数据存储与查询需求,特别适用于需要快速读写大量非结构化或半结构化数据的应用场景。NoSQL数据库通过牺牲部分一致性来换取更高的可扩展性和性能,支持分布式部署,能够有效应对互联网时代的海量数据挑战。 ... [详细]
  • 第二章:Kafka基础入门与核心概念解析
    本章节主要介绍了Kafka的基本概念及其核心特性。Kafka是一种分布式消息发布和订阅系统,以其卓越的性能和高吞吐量而著称。最初,Kafka被设计用于LinkedIn的活动流和运营数据处理,旨在高效地管理和传输大规模的数据流。这些数据主要包括用户活动记录、系统日志和其他实时信息。通过深入解析Kafka的设计原理和应用场景,读者将能够更好地理解其在现代大数据架构中的重要地位。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • Python 实战:异步爬虫(协程技术)与分布式爬虫(多进程应用)深入解析
    本文将深入探讨 Python 异步爬虫和分布式爬虫的技术细节,重点介绍协程技术和多进程应用在爬虫开发中的实际应用。通过对比多进程和协程的工作原理,帮助读者理解两者在性能和资源利用上的差异,从而在实际项目中做出更合适的选择。文章还将结合具体案例,展示如何高效地实现异步和分布式爬虫,以提升数据抓取的效率和稳定性。 ... [详细]
  • 揭秘腾讯云CynosDB计算层设计优化背后的不为人知的故事与技术细节
    揭秘腾讯云CynosDB计算层设计优化背后的不为人知的故事与技术细节 ... [详细]
  • 作为140字符的开创者,Twitter看似简单却异常复杂。其简洁之处在于仅用140个字符就能实现信息的高效传播,甚至在多次全球性事件中超越传统媒体的速度。然而,为了支持2亿用户的高效使用,其背后的技术架构和系统设计则极为复杂,涉及高并发处理、数据存储和实时传输等多个技术挑战。 ... [详细]
  • V8不仅是一款著名的八缸发动机,广泛应用于道奇Charger、宾利Continental GT和BossHoss摩托车中。自2008年以来,作为Chromium项目的一部分,V8 JavaScript引擎在性能优化和技术创新方面取得了显著进展。该引擎通过先进的编译技术和高效的垃圾回收机制,显著提升了JavaScript的执行效率,为现代Web应用提供了强大的支持。持续的优化和创新使得V8在处理复杂计算和大规模数据时表现更加出色,成为众多开发者和企业的首选。 ... [详细]
  • 利用ZFS和Gluster实现分布式存储系统的高效迁移与应用
    本文探讨了在Ubuntu 18.04系统中利用ZFS和Gluster文件系统实现分布式存储系统的高效迁移与应用。通过详细的技术分析和实践案例,展示了这两种文件系统在数据迁移、高可用性和性能优化方面的优势,为分布式存储系统的部署和管理提供了宝贵的参考。 ... [详细]
  • TypeScript 实战分享:Google 工程师深度解析 TypeScript 开发经验与心得
    TypeScript 实战分享:Google 工程师深度解析 TypeScript 开发经验与心得 ... [详细]
  • REST API 时代落幕,GraphQL 持续引领未来
    尽管REST API已广泛使用多年,但在深入了解GraphQL及其解决的核心问题后,我深感其将引领未来的API设计趋势。GraphQL不仅提高了数据查询的效率,还增强了灵活性和性能,有望成为API开发的新标准。 ... [详细]
  • Facebook 强一致性键值存储 ZippyDB 架构简介
    更多内容关注微信公众号:fullstack888Facebook工程团队最近发布了一篇博客文章,阐述了如何构建其通用的键值存储的,也就是Z ... [详细]
  • SocialFi 的未来:数据所有权、更公平的价值分配和行为数据的价值化
    SocialFi本质上是对Web2中心化社交平台的一次价值解构。撰文:Morty ... [详细]
  • 在嵌入式Linux系统中,性能低下通常由CPU、内存和I/O三个关键因素引起。为了有效提升系统性能,首先需要识别并定位性能瓶颈。通过综合分析这些瓶颈,可以采取针对性的优化措施,如调整内核参数、优化算法和改进数据结构等,从而显著提高系统的整体性能。 ... [详细]
  • 本文深入解析了Java 8并发编程中的`AtomicInteger`类,详细探讨了其源码实现和应用场景。`AtomicInteger`通过硬件级别的原子操作,确保了整型变量在多线程环境下的安全性和高效性,避免了传统加锁方式带来的性能开销。文章不仅剖析了`AtomicInteger`的内部机制,还结合实际案例展示了其在并发编程中的优势和使用技巧。 ... [详细]
  • 并发编程入门:初探多任务处理技术
    并发编程入门:探索多任务处理技术并发编程是指在单个处理器上高效地管理多个任务的执行过程。其核心在于通过合理分配和协调任务,提高系统的整体性能。主要应用场景包括:1) 将复杂任务分解为多个子任务,并分配给不同的线程,实现并行处理;2) 通过同步机制确保线程间协调一致,避免资源竞争和数据不一致问题。此外,理解并发编程还涉及锁机制、线程池和异步编程等关键技术。 ... [详细]
author-avatar
浪奔西安
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有