MicroStream 简介:Java 中的超快速序列化
MicroStream 是一种非常有趣甚至大胆的 Java 应用程序数据持久化方法。 它建议完全回避服务器-数据存储的复杂性,而是提供一个在应用程序本身内部运行的对象持久层。 Oracle 已将 MicroStream 整合到其 Helidon 微服务框架中,这可以看作是对该方法的主要认可。
继续阅读以了解有关 MicroStream 及其开源对象图持久层的更多信息。
重新考虑 Java 序列化
从某种意义上说,您可以将 MicroStream 视为序列化思想的重做。
传统的 Java 序列化有几个令人讨厌的限制(包括安全漏洞),促使 Oracle 在 2018 年将其称为“可怕的错误”。但是能够在运行时简单地存储和检索对象图的固有想法仍然是可行的.
所需要的是一个非常优秀的实施。 这就是 MicroStream 介入的地方。
微流缓存实现
MicroStream 还实现了 JSR-107(JCache 规范)。 这意味着无论是否启用 MicroStream 的持久性和存储部分,您都可以将 MicroStream 用作缓存层(例如使用 Hibernate/JPA)。
这使得使用 MicroStream 作为一站式缓存和持久性解决方案变得很有吸引力,尤其是在微服务的上下文中。
MicroStream 序列化改进
也许 MicroStream 对传统序列化所做的最重要的改进是能够仅保留对象图的一部分。 否则,任何解决方案都无法满足实际应用程序的需求。
MicroStream 还通过自动建模或开发人员定义的配置来处理不断变化的类结构(所有应用程序中的现实)。
此外,与传统的序列化不同,MicroStream 能够处理所有可持久化的 Java 结构。
MicroStream 数据根
在 MicroStream 中,将由持久化引擎管理的对象图以称为根节点的根节点开始 DataRoot
.
这 DataRoot
object 可以是任何类型,它被设置在 StorageManager
如清单 1 中所示的实例。请注意,无论何时启动存储管理器,它都会自动重新水化来自最后一个持久会话的图形,这发生在 storeRoot()
称呼。
清单 1. 启动存储管理器并分配根目录
public class MyDataRoot { private String stuff; public DataRoot() { super(); } public String getContent() { return this.stuff; } public void setContent(Object myWonderfulStuff) { this.stuff = myWonderfulStuff ; } @Override public String toString() { return "Root: " + this.stuff; }}// ...final EmbeddedStorageManager storageManager = EmbeddedStorage.start();System.out.println(storageManager.root());storageManager.setRoot(MyDataRoot);storageManager.storeRoot(); // Saves the state
在清单 1 中,该类有一个成员,可以是任何对象。 在真实世界的应用程序中,您可能会建立一个业务模型。 您可以使用地图作为数据模型并将所有内容存储为键值对。 MicroStream 可以处理任何你扔给它的东西,而且它足够灵活,可以随着你不断变化的类结构而发展。
定义文件路径
StorageManager
带有几个配置选项。 其中最重要的一项是数据存储位置的路径。 您可以在清单 2 中看到实际效果。
清单 2. 设置数据存储路径
final MyDataRoot myRoot = new MyDataRoot();final EmbeddedStorageManager storageManager = EmbeddedStorage.start( myRoot, Paths.get("data") );
您可以优雅地关闭引擎 storageManager.shutdown();
.
MicroStream 中的多线程
在多线程应用程序代码中,变异数据和持久数据必须同步。 Microstream 为此目的提供了一个 Lambda,如清单 3 所示。
清单 3. 同步访问
XThreads.executeSynchronized(() -> { root.changeData(); storageManager.store(root); });
微流配置
MicroStream 有多种配置选项,您可以通过声明或编程方式进行设置。
例如,您可以配置作为文件管理器中读/写操作基础的 NIO(非阻塞 IO)文件系统,如清单 4 所示。此示例取自 MicroStream 文档。
清单 4. 配置 NIO 文件系统
NioFileSystem fileSystem = NioFileSystem.New();EmbeddedStorageManager storageManager = EmbeddedStorageFoundation.New() .setConfiguration( StorageConfiguration.Builder() .setStorageFileProvider( Storage.FileProviderBuilder(fileSystem) .setDirectory(fileSystem.ensureDirectoryPath("storageDir")) .createFileProvider() ) .setChannelCountProvider(StorageChannelCountProvider.New(4)) .setBackupSetup(StorageBackupSetup.New( fileSystem.ensureDirectoryPath("backupDir") )) .createConfiguration() ) .createEmbeddedStorageManager();
您还可以从 JSON、YAML 和 XML 加载外部配置。
在 MicroStream 中查询
MicroStream 方法的一个有趣结果是不需要专门的查询语言,如 SQL 或 HQL 或标准 API。 您可以简单地使用标准 Java 来导航您的运行时图并选择结果。 您可以使用老式循环或函数式流 API 来遍历关联并测试您寻找的一个或多个属性。 MicroStream 给出的示例在清单 5 中,但任何典型的方法都可以使用。
清单 5. 在图中查找对象
public ListgetUnAvailableArticles() { return shop.getArticles().stream() .filter(a -> !a.available()) .collect(Collectors.toList()) ;}
结果是,因为您的数据层存储的是普通的旧 Java 对象,所以您可以使用普通 Java 进行查询。
MicroStream 存储选项
虽然默认是文件系统,但 MicroStream 是一个能够与其他持久性解决方案一起工作的抽象层。 它甚至可以通过连接器针对 MariaDB 等关系数据库管理系统运行。 清单 6 向您展示了这一点。
清单 6. 使用 MariaDB RDBMS 连接器
MariaDbDataSource dataSource = new MariaDbDataSource();dataSource.setUrl("jdbc:mysql://host:3306/awesomedb");dataSource.setUser("user");dataSource.setPassword("secret");SqlFileSystem fileSystem = SqlFileSystem.New(SqlConnector.Caching(SqlProviderMariaDb.New(dataSource)));EmbeddedStorage.start(fileSystem.ensureDirectoryPath("microstream_storage"));
这是一种非常强大的能力,可以无缝地从 Java 对象到数据库再返回,尤其是与使用 Hibernate 等对象关系映射器 (ORM) 所涉及的工作相比。
对于使用 Redis 和 MongoDB 等非关系数据存储以及 Amazon S3 和 Oracle Cloud Storage 等云数据存储,存在类似的支持。
微流存储模式
MicroStream 支持两种存储模式,lazy 和 eager。 默认情况下,MicroStream 使用惰性存储。
在惰性存储中,一旦一个对象被持久化,它就不会被再次存储,即使被修改。 要保留修改后的对象,您必须显式调用以存储它。 除非开发人员要求,否则这具有避免与底层存储系统交互的明显性能优势。
在急切存储中,MicroStream 将在持久实例发生变化时自动更新它们。 您可以在清单 7 中看到如何启用预先存储。
清单 7. Eager 存储
Storer storer = storage.createEagerStorer(); storer.store(myData); storer.commit();
瞬变场修饰符
MicroStream 透明地实现了 transient 修饰符,这样的成员不会被引擎持久化。 这提供了一种选择退出存储的简单方法。
微流性能
MicroStream 的首席开发人员在此处简要描述了框架的性能影响。 这是一篇简短而值得一读的文章。 它解释了系统如何在不丢失引用完整性的情况下通过一次读取类布局元数据,然后监视它的变化来实现一流的性能。 它还将帮助您了解 MicroStream 如何减轻反射的限制。
MicroStream 的另一个有趣的方面是它如何跟踪已经从图形中分离出来的实体(即,已经被垃圾收集)因此需要从存储中删除。 这在 MicroStream 中被称为内务处理,代表了一项令人印象深刻的技术成就。
MicroStream 存储和加载运行对象图的方法是开创性的,并且可能会在未来改变 Java 开发的格局。 这是对传统服务数据存储架构的意外背离,但却是一个受欢迎的架构,它消除了主要的复杂性来源。
在考虑 Java 应用程序的持久性需求时,MicroStream 非常值得仔细研究。