From bb5d5e89ac89cf570df93c9a81e2f6c7f8432882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=99=BC=E9=87=8C=E5=95=AA=E5=95=A6=E5=98=A3?= Date: Thu, 12 Dec 2019 09:50:18 +0800 Subject: [PATCH] =?UTF-8?q?26=20=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/1.7/26.md | 152 ++++++++++++++++++++++++------------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/docs/1.7/26.md b/docs/1.7/26.md index 77b4375..e03122d 100644 --- a/docs/1.7/26.md +++ b/docs/1.7/26.md @@ -1,16 +1,16 @@ -# Custom Serialization for Managed State +# Custom Serialization for Managed State 用于托管状态的自定义序列化 -This page is targeted as a guideline for users who require the use of custom serialization for their state, covering how to provide a custom state serializer as well as guidelines and best practices for implementing serializers that allow state schema evolution. +此页面是针对需要为其状态使用自定义序列化的用户提供的指南,包括如何提供自定义状态序列化程序以及实现允许状态架构演变的序列化程序的指南和最佳实践。 -If you’re simply using Flink’s own serializers, this page is irrelevant and can be ignored. +如果您只是使用Flink自己的序列化程序,则此页面是不相关的,可以忽略。 -## Using custom state serializers +## Using custom state serializers 使用自定义状态序列化程序 -When registering a managed operator or keyed state, a `StateDescriptor` is required to specify the state’s name, as well as information about the type of the state. The type information is used by Flink’s [type serialization framework](../../types_serialization.html) to create appropriate serializers for the state. +注册受管理的运算符或键状态时,需要`StateDescriptor` 来指定状态的名称,以及有关状态类型的信息。类型信息由flink的[类型序列化框架](../../types_serialization.html)为该状态创建适当的序列化程序。 -It is also possible to completely bypass this and let Flink use your own custom serializer to serialize managed states, simply by directly instantiating the `StateDescriptor` with your own `TypeSerializer` implementation: +还可以完全绕过这一点,让flink使用您自己的自定义串行器序列化受管理的状态,简单地通过直接实例化`StateDescriptor` 和您自己的 `TypeSerializer` 实现: @@ -42,21 +42,21 @@ checkpointedState = getRuntimeContext.getListState(descriptor) -## State serializers and schema evolution +## State serializers and schema evolution 状态序列化程序和架构演进 -This section explains the user-facing abstractions related to state serialization and schema evolution, and necessary internal details about how Flink interacts with these abstractions. +本节解释与状态序列化和模式演化相关的面向用户的抽象,以及关于Flink如何与这些抽象交互的必要的内部细节。 -When restoring from savepoints, Flink allows changing the serializers used to read and write previously registered state, so that users are not locked in to any specific serialization schema. When state is restored, a new serializer will be registered for the state (i.e., the serializer that comes with the `StateDescriptor` used to access the state in the restored job). This new serializer may have a different schema than that of the previous serializer. Therefore, when implementing state serializers, besides the basic logic of reading / writing data, another important thing to keep in mind is how the serialization schema can be changed in the future. +从保存点恢复时,flink允许更改用于读取和写入先前注册状态的Serializer,以便用户不会锁定到任何特定的序列化架构中。当恢复状态时,将为状态注册新的序列化程序(即,使用 `StateDescriptor` 来访问还原作业中的状态的序列化程序)。这个新的串行化器可以具有比先前串行化器的模式不同的模式。因此,当实现状态序列化程序时,除了读/写数据的基本逻辑之外,要记住的另一个重要问题是如何在将来改变序列化模式。 -When speaking of _schema_, in this context the term is interchangeable between referring to the _data model_ of a state type and the _serialized binary format_ of a state type. The schema, generally speaking, can change for a few cases: +说到 _schema_,在这种情况下,该术语在引用状态类型的 _data model_ 和状态类型的 _serialized binary format_ 之间是可互换的。一般而言,模式可以更改几种情况: -1. Data schema of the state type has evolved, i.e. adding or removing a field from a POJO that is used as state. -2. Generally speaking, after a change to the data schema, the serialization format of the serializer will need to be upgraded. -3. Configuration of the serializer has changed. +1. 状态类型的数据模式已经发展,即从用作状态的POJO中添加或删除字段。 +2. 一般来说,在对数据模式进行更改后,序列化程序的序列化格式将需要升级。 +3. 序列化程序的配置已更改。 -In order for the new execution to have information about the _written schema_ of state and detect whether or not the schema has changed, upon taking a savepoint of an operator’s state, a _snapshot_ of the state serializer needs to be written along with the state bytes. This is abstracted a `TypeSerializerSnapshot`, explained in the next subsection. +为了使新的执行具有关于 _written schema_ OF状态的信息并检测模式是否已改变,在获取操作者的状态的保存点时,需要将状态串行化器的 _snapshot_ of与状态字节一起写入。这被抽象化了下一个小节中解释的`TypeSerializerSnapshot`。 -### The `TypeSerializerSnapshot` abstraction +### The `TypeSerializerSnapshot` abstraction “TypeSerializerSnapail”抽象 @@ -85,92 +85,92 @@ public abstract class TypeSerializer { -A serializer’s `TypeSerializerSnapshot` is a point-in-time information that serves as the single source of truth about the state serializer’s write schema, as well as any additional information mandatory to restore a serializer that would be identical to the given point-in-time. The logic about what should be written and read at restore time as the serializer snapshot is defined in the `writeSnapshot` and `readSnapshot` methods. +串行器 `TypeSerializerSnapshot` 是一个时间点信息,它作为关于状态串行器的写模式的唯一的事实源,以及任何附加的信息,这些信息必须恢复与给定的时间点相同的串行器。在恢复时应该写入和读取的逻辑,因为序列化快照是在`writeSnapshot`和 `readSnapshot`方法中定义的。 -Note that the snapshot’s own write schema may also need to change over time (e.g. when you wish to add more information about the serializer to the snapshot). To facilitate this, snapshots are versioned, with the current version number defined in the `getCurrentVersion` method. On restore, when the serializer snapshot is read from savepoints, the version of the schema in which the snapshot was written in will be provided to the `readSnapshot` method so that the read implementation can handle different versions. +请注意,快照本身的写入模式也可能需要随着时间的推移而更改(例如,当您希望向快照中添加更多有关序列化程序的信息时)。为了方便这一点,快照是版本化的,在`getCurrentVersion`方法中定义了当前版本号。在还原时,当从保存点读取序列化程序快照时,将把写入快照的架构的版本提供给 `readSnapshot` 方法,以便读取实现能够处理不同的版本。 -At restore time, the logic that detects whether or not the new serializer’s schema has changed should be implemented in the `resolveSchemaCompatibility` method. When previous registered state is registered again with new serializers in the restored execution of an operator, the new serializer is provided to the previous serializer’s snapshot via this method. This method returns a `TypeSerializerSchemaCompatibility` representing the result of the compatibility resolution, which can be one of the following: +在恢复时,检测新序列化程序的模式是否已更改的逻辑应该在 `resolveSchemaCompatibility`方法中实现。当在已还原的操作符的执行中使用新的序列化器再次注册前一个已注册状态时,将通过此方法将新的序列化程序提供给前一个序列化程序的快照。此方法返回一个 `TypeSerializerSchemaCompatibility` ,它表示兼容性解析的结果,可以是以下内容之一: -1. **`TypeSerializerSchemaCompatibility.compatibleAsIs()`**: this result signals that the new serializer is compatible, meaning that the new serializer has identical schema with the previous serializer. It is possible that the new serializer has been reconfigured in the `resolveSchemaCompatibility` method so that it is compatible. -2. **`TypeSerializerSchemaCompatibility.compatibleAfterMigration()`**: this result signals that the new serializer has a different serialization schema, and it is possible to migrate from the old schema by using the previous serializer (which recognizes the old schema) to read bytes into state objects, and then rewriting the object back to bytes with the new serializer (which recognizes the new schema). -3. **`TypeSerializerSchemaCompatibility.incompatible()`**: this result signals that the new serializer has a different serialization schema, but it is not possible to migrate from the old schema. +1. **`TypeSerializerSchemaCompatibility.compatibleAsIs()`**: 这导致新的串行器兼容,这意味着新的串行器与先前的串行器具有相同的模式。可以在 `resolveSchemaCompatibility`方法中重新配置新的串行器,使其兼容。 +2. **`TypeSerializerSchemaCompatibility.compatibleAfterMigration()`**: 该结果信号使得新的串行化器具有不同的串行化模式,并且可以通过使用先前的串行器(其识别旧模式)将字节读入到状态对象,然后用新的串行器(其识别新模式)将该对象重写回字节来从旧模式迁移。 +3. **`TypeSerializerSchemaCompatibility.incompatible()`**: 此结果表明新序列化程序具有不同的序列化架构,但无法从旧模式迁移。 -The last bit of detail is how the previous serializer is obtained in the case that migration is required. Another important role of a serializer’s `TypeSerializerSnapshot` is that it serves as a factory to restore the previous serializer. More specifically, the `TypeSerializerSnapshot` should implement the `restoreSerializer` method to instantiate a serializer instance that recognizes the previous serializer’s schema and configuration, and can therefore safely read data written by the previous serializer. +最后一个细节是在需要迁移的情况下如何获得前一个序列化程序。序列化程序的“TypeSerializerSnapail”的另一个重要作用是它作为一个工厂来恢复以前的序列化程序。更具体地说, `TypeSerializerSnapshot` 应该实现`restoreSerializer`方法,以实例化一个序列化器实例,该实例识别上一个序列化程序的模式和配置,因此可以安全地读取由前一个序列化程序编写的数据。 -### How Flink interacts with the `TypeSerializer` and `TypeSerializerSnapshot` abstractions +### How Flink interacts with the `TypeSerializer` and `TypeSerializerSnapshot` abstractions flink如何与“排版器”和“排版快照”抽象进行交互抽象 -To wrap up, this section concludes how Flink, or more specifically the state backends, interact with the abstractions. The interaction is slightly different depending on the state backend, but this is orthogonal to the implementation of state serializers and their serializer snapshots. +为了总结,本节将总结Flink,或更具体而言,状态后端如何与抽象进行交互。根据状态后端,交互略有不同,但这与状态串行器及其串行器快照的实现是正交的。 -#### Off-heap state backends (e.g. `RocksDBStateBackend`) +#### Off-heap state backends (e.g. `RocksDBStateBackend`) 堆外状态后端(例如“RocksDBStateBackend”) -1. **Register new state with a state serializer that has schema _A_** - * the registered `TypeSerializer` for the state is used to read / write state on every state access. - * State is written in schema _A_. -2. **Take a savepoint** - * The serializer snapshot is extracted via the `TypeSerializer#snapshotConfiguration` method. - * The serializer snapshot is written to the savepoint, as well as the already-serialized state bytes (with schema _A_). -3. **Restored execution re-accesses restored state bytes with new state serializer that has schema _B_** - * The previous state serializer’s snapshot is restored. - * State bytes are not deserialized on restore, only loaded back to the state backends (therefore, still in schema _A_). - * Upon receiving the new serializer, it is provided to the restored previous serializer’s snapshot via the `TypeSerializer#resolveSchemaCompatibility` to check for schema compatibility. -4. **Migrate state bytes in backend from schema _A_ to schema _B_** - * If the compatibility resolution reflects that the schema has changed and migration is possible, schema migration is performed. The previous state serializer which recognizes schema _A_ will be obtained from the serializer snapshot, via `TypeSerializerSnapshot#restoreSerializer()`, and is used to deserialize state bytes to objects, which in turn are re-written again with the new serializer, which recognizes schema _B_ to complete the migration. All entries of the accessed state is migrated all-together before processing continues. - * If the resolution signals incompatibility, then the state access fails with an exception. +1. **Register new state with a state serializer that has schema _A_ 使用具有架构的状态序列化程序注册新状态** + * 用于该状态的注册的`TypeSerializer` 被用于在每个状态访问上的读/写状态。 + * 状态以架构写入模式 _A_. +2. **Take a savepoint 获取保存点** + * 序列化程序快照是通过`TypeSerializer#snapshotConfiguration`方法提取的。 + * 序列化器快照被写入保存点以及已经序列化的状态字节(带有schema_A_)。 +3. **还原后的执行使用具有架构的新状态序列化程序重新访问已恢复的状态字节。_B_** + * 还原以前的状态序列化程序的快照。 + * Tate字节在还原时不会反序列化,只会加载回状态后端(因此,仍然处于schema_A_)中。 + * 在接收到新的序列化程序后,将通过`TypeSerializer#resolveSchemaCompatibility`将其提供给还原后的前一个序列化程序的快照,以检查模式兼容性。 +4. **Migrate state bytes in backend from schema _A_ to schema _B_ 从模式迁移后端的状态字节** + * 如果兼容性解决方案反映了架构已更改并可能迁移,则执行架构迁移。识别架构_A_的上一个状态串行器将从串行器快照通过“TypeEriizerSnapshot#RestorReservalizer()”获得,并用于将状态字节反序列化为对象,这些对象又再次与新的序列化程序重新写入,新的序列化程序会识别架构_B_来完成迁移。在处理继续之前,被访问的状态的所有条目都被一起迁移到一起。 + * 如果解析表明不兼容,则状态访问将失败,但有异常。 -#### Heap state backends (e.g. `MemoryStateBackend`, `FsStateBackend`) +#### Heap state backends (e.g. `MemoryStateBackend`, `FsStateBackend`) 堆状态后端(例如“MemoryStateBackend”、“FsStateBackend”) -1. **Register new state with a state serializer that has schema _A_** - * the registered `TypeSerializer` is maintained by the state backend. -2. **Take a savepoint, serializing all state with schema _A_** - * The serializer snapshot is extracted via the `TypeSerializer#snapshotConfiguration` method. - * The serializer snapshot is written to the savepoint. - * State objects are now serialized to the savepoint, written in schema _A_. -3. **On restore, deserialize state into objects in heap** - * The previous state serializer’s snapshot is restored. - * The previous serializer, which recognizes schema _A_, is obtained from the serializer snapshot, via `TypeSerializerSnapshot#restoreSerializer()`, and is used to deserialize state bytes to objects. - * From now on, all of the state is already deserialized. -4. **Restored execution re-accesses previous state with new state serializer that has schema _B_** - * Upon receiving the new serializer, it is provided to the restored previous serializer’s snapshot via the `TypeSerializer#resolveSchemaCompatibility` to check for schema compatibility. - * If the compatibility check signals that migration is required, nothing happens in this case since for heap backends, all state is already deserialized into objects. - * If the resolution signals incompatibility, then the state access fails with an exception. -5. **Take another savepoint, serializing all state with schema _B_** - * Same as step 2., but now state bytes are all in schema _B_. +1. **向具有的状态序列化程序注册新状态** + * 注册的“TypeSerializer”由州后端维护。 +2. **接受保存点,使用schema_A_** + * 序列化程序快照是通过‘TypeSeriizer#快照配置’方法提取的。 + * 序列化程序快照将写入保存点。 + * 状态对象现在被序列化到保存点,在schema_a_中写入。 +3. **在还原时,将状态反序列化为堆中的对象** + * 还原以前的状态序列化程序的快照。 + * 上一个序列化程序识别SCHEMA_A_,它通过‘TypeSerializerSnapshot#RestoreSeriizer()’从序列化器快照中获得,并用于将状态字节反序列化为对象。 + * 从现在开始,所有的州都已经被反序列化了。 +4. **恢复的执行使用具有schema_b_的新的状态序列化程序重新访问先前的状态** + * 在接收到新的序列化程序后,将通过“TypeSeriizer#解析式模式兼容性”将其提供给还原后的前一个序列化程序的快照,以检查模式兼容性。 + * 如果需要迁移的兼容性检查信号,在此情况下,由于堆后端,所有状态都已被反序列化为对象。 + * 如果解析表明不兼容,则状态访问将失败,但有异常。 +5. **接受另一个保存点,使用schema_B_** + * 与步骤2相同,但现在状态字节都在schema_B_中。 -## Implementation notes and best practices +## Implementation notes and best practices 执行说明和最佳做法 -#### 1\. Flink restores serializer snapshots by instantiating them with their classname +#### 1\. Flink通过用类名实例化序列化器快照来还原它们。 -A serializer’s snapshot, being the single source of truth for how a registered state was serialized, serves as an entry point to reading state in savepoints. In order to be able to restore and access previous state, the previous state serializer’s snapshot must be able to be restored. +序列化程序的快照是如何序列化注册状态的唯一真实来源,它是在保存点中读取状态的入口点。为了能够恢复和访问以前的状态,必须能够还原前一个状态序列化程序的快照。 -Flink restores serializer snapshots by first instantiating the `TypeSerializerSnapshot` with its classname (written along with the snapshot bytes). Therefore, to avoid being subject to unintended classname changes or instantiation failures, `TypeSerializerSnapshot` classes should: +flink通过首先用其ClassName(与快照字节一起编写)实例化“TypeEriizerSnapshot”来恢复序列化程序快照。因此,为避免受到意外的ClassName更改或实例化失败的影响,“TypeLiizerSnapshot”类应: -* avoid being implemented as anonymous classes or nested classes, -* have a public, nullary constructor for instantiation +* 避免被实现为匿名类或嵌套类, +* 具有用于实例化的公共零构造函数。 -#### 2\. Avoid sharing the same `TypeSerializerSnapshot` class across different serializers +#### 2\. 避免在不同的Serializer上共享相同的“TypeEriizerSnapshot”类 -Since schema compatibility checks goes through the serializer snapshots, having multiple serializers returning the same `TypeSerializerSnapshot` class as their snapshot would complicate the implementation for the `TypeSerializerSnapshot#resolveSchemaCompatibility` and `TypeSerializerSnapshot#restoreSerializer()` method. +由于架构兼容性检查通过串行器快照,因此具有多个Serializer返回相同的“TypeEriizerSnapshot”类,因为它们的快照会使“TypeEriizerSnapshot#ResolvescheCompatibility”和“TypeEriizerSnapshot#ResReservisionalizer()”方法的实现复杂化。 -This would also be a bad separation of concerns; a single serializer’s serialization schema, configuration, as well as how to restore it, should be consolidated in its own dedicated `TypeSerializerSnapshot` class. +这也是一个错误的关注点分离;一个序列化程序的序列化模式、配置以及如何恢复它,应该合并到它自己的专用`TypeSerializerSnapail‘类中。 -#### 3\. Use the `CompositeSerializerSnapshot` utility for serializers that contain nested serializers +#### 3\. 对于包含嵌套序列化程序的序列化程序,请使用“CompositeSerializerSnapail”实用程序 -There may be cases where a `TypeSerializer` relies on other nested `TypeSerializer`s; take for example Flink’s `TupleSerializer`, where it is configured with nested `TypeSerializer`s for the tuple fields. In this case, the snapshot of the most outer serializer should also contain snapshots of the nested serializers. +在有些情况下,`TypeSerializer` 依赖其他嵌套的`TypeSerializer`;例如Flink的`TupleSerializer`,其中为元组字段配置了嵌套的`TypeSerializer`。在这种情况下,大多数外部序列化程序的快照还应该包含嵌套序列化器的快照。 -The `CompositeSerializerSnapshot` can be used specifically for this scenario. It wraps the logic of resolving the overall schema compatibility check result for the composite serializer. For an example of how it should be used, one can refer to Flink’s [ListSerializerSnapshot](https://github.com/apache/flink/blob/master/flink-core/src/main/java/org/apache/flink/api/common/typeutils/base/ListSerializerSnapshot.java) implementation. +`CompositeSerializerSnapshot`可专门用于此场景。它封装了解析复合序列化程序的总体模式兼容性检查结果的逻辑。关于应该如何使用它的示例,可以参考Flink的[ListSerializerSnapshot](https://github.com/apache/flink/blob/master/flink-core/src/main/java/org/apache/flink/api/common/typeutils/base/ListSerializerSnapshot.java)实现。 -## Migrating from deprecated serializer snapshot APIs before Flink 1.7 +## Migrating from deprecated serializer snapshot APIs before Flink 1.7 在flink1.7之前从不建议使用的序列化程序快照API迁移1.7 -This section is a guide for API migration from serializers and serializer snapshots that existed before Flink 1.7. +本节是在FLink1.7之前存在的来自Serializer和Serializer快照的API迁移指南。 -Before Flink 1.7, serializer snapshots were implemented as a `TypeSerializerConfigSnapshot` (which is now deprecated, and will eventually be removed in the future to be fully replaced by the new `TypeSerializerSnapshot` interface). Moreover, the responsibility of serializer schema compatibility checks lived within the `TypeSerializer`, implemented in the `TypeSerializer#ensureCompatibility(TypeSerializerConfigSnapshot)` method. +在Flink 1.7之前,序列化器快照被实现为`TypeSerializerConfigSnapshot` (现在已不再推荐,最终将被删除,由新的“TypeSerializerSnapail”接口完全取代)。此外,序列化程序模式兼容性检查的责任存在于在`TypeSerializer#ensureCompatibility(TypeSerializerConfigSnapshot)`方法中实现的“TypeSerializer”中。 -Another major difference between the new and old abstractions is that the deprecated `TypeSerializerConfigSnapshot` did not have the capability of instantiating the previous serializer. Therefore, in the case where your serializer still returns a subclass of `TypeSerializerConfigSnapshot` as its snapshot, the serializer instance itself will always be written to savepoints using Java serialization so that the previous serializer may be available at restore time. This is very undesirable, since whether or not restoring the job will be successful is susceptible to availability of the previous serializer’s class, or in general, whether or not the serializer instance can be read back at restore time using Java serialization. This means that you be limited to the same serializer for your state, and could be problematic once you want to upgrade serializer classes or perform schema migration. +新旧抽象之间的另一个主要区别是,不推荐的`TypeSerializerConfigSnapshot` 不具有实例化前一个序列化程序的能力。因此,在序列化程序仍然返回‘ `TypeSerializerConfigSnapshot`子类作为其快照的情况下,序列化程序实例本身将始终被写入使用Java序列化的保存点,以便在还原时可以使用以前的序列化程序。这是非常不可取的,因为还原作业是否成功容易受到上一个序列化程序类的可用性的影响,或者通常情况下,序列化程序实例是否可以使用Java序列化在还原时读取。这意味着您的状态仅限于相同的序列化程序,并且一旦您想升级序列化程序类或执行架构迁移,可能会出现问题。 -To be future-proof and have flexibility to migrate your state serializers and schema, it is highly recommended to migrate from the old abstractions. The steps to do this is as follows: +为了便于将来的验证,并具有迁移状态序列化器和模式的灵活性,强烈建议从旧的抽象迁移。这样做的步骤如下: -1. Implement a new subclass of `TypeSerializerSnapshot`. This will be the new snapshot for your serializer. -2. Return the new `TypeSerializerSnapshot` as the serializer snapshot for your serializer in the `TypeSerializer#snapshotConfiguration()` method. -3. Restore the job from the savepoint that existed before Flink 1.7, and then take a savepoint again. Note that at this step, the old `TypeSerializerConfigSnapshot` of the serializer must still exist in the classpath, and the implementation for the `TypeSerializer#ensureCompatibility(TypeSerializerConfigSnapshot)` method must not be removed. The purpose of this process is to replace the `TypeSerializerConfigSnapshot` written in old savepoints with the newly implemented `TypeSerializerSnapshot` for the serializer. -4. Once you have a savepoint taken with Flink 1.7, the savepoint will contain `TypeSerializerSnapshot` as the state serializer snapshot, and the serializer instance will no longer be written in the savepoint. At this point, it is now safe to remove all implementations of the old abstraction (remove the old `TypeSerializerConfigSnapshot` implementation as will as the `TypeSerializer#ensureCompatibility(TypeSerializerConfigSnapshot)` from the serializer). +1. 实现一个新的子类`TypeSerializerSnapshot`。这将是序列化程序的新快照。 +2. 返回新的`TypeSerializerSnapshot`作为序列化程序的快照,在`TypeSerializer#snapshotConfiguration()`方法中。 +3. 从在flink1.7之前存在的savepoint还原作业,然后再次获取保存点。请注意,在此步骤中,序列化程序中的旧的 `TypeSerializerConfigSnapshot`必须仍然存在于类路径中,并且必须不删除`TypeSerializer#ensureCompatibility(TypeSerializerConfigSnapshot)` 方法的实现。此过程的目的是用新实现的序列化程序的 `TypeSerializerConfigSnapshot`替换旧存储点中写入的 `TypeSerializerSnapshot` 。 +4. 一旦您使用了flink1.7的保存点,则保存点将包含作为状态序列化程序快照的“TypeerializerSnapshot”,并且序列化程序实例将不再写入保存点。在这一点上,现在可以安全地删除旧的抽象的所有实现(删除旧的“类型EriizerConfigSnapshot”实现),这将是串行器的“TypeErierConfigure#Ensure兼容性(类型EriizerConfigSnapshot)”。 -- GitLab