1. 依賴
前面兩篇我已經講過 Flink getRuntimeContext().getMapState的時候發生了什麼?以及 Flink StateDescriptor Name的作用。
今天我們在這個的基礎上一起來看一下,爲什麼 key state 僅僅與 key 有關,無論我取數據還是修改數據,僅僅只能取到(修改)這個key 對應的那一部分。
2. 以 RocksDBListState 爲例
2.1 add、get 方法講解
我們以 RocksDBListState 爲例。分別查看 get 方法 和 add 方法 get 方法 通過源碼我們可以追蹤到 byte[] key = serializeCurrentKeyWithGroupAndNamespace();
byte[] valueBytes = backend.db.get(columnFamily, key);
return deserializeList(valueBytes);
同理 add 方法
backend.db.merge(
columnFamily,
writeOptions,
serializeCurrentKeyWithGroupAndNamespace(),
serializeValue(value, elementSerializer)
);
columnFamily 就不用說了,具體可以參考 Flink StateDescriptor Name的作用,主要就是 ColumnFamily Handle
writeOptions rockdb 的寫控制,比如說是 sync 還是 async等
serializeValue 就是把 value 序列化成 byte 數組。
2.2 關鍵性方法講解
關鍵性的方法來了 serializeCurrentKeyWithGroupAndNamespace, 就是序列化 key key-group namespace( 當時window 的時候 就是window( 如:TimeWindow{start=1590502000000, end=1590503000000} ) 否則就是 VoidNamespace), **它的作用就是 ColumnFamily 下的 key**跟隨 serializeCurrentKeyWithGroupAndNamespace 方法
// the bytes for the serialized composite key of key-group, key, namespace
// key-group key namespace 序列化爲 rockdb 在指定 column family 下的 key,value 就是 value
byte[] serializeCurrentKeyWithGroupAndNamespace() {
return sharedKeyNamespaceSerializer.buildCompositeKeyNamespace(currentNamespace, namespaceSerializer);
}
3. 結論
像 add clear update 等方法都會用到 serializeCurrentKeyWithGroupAndNamespace 這也就是爲什麼,key state 只會有 key 有關,因爲去取值或者修改的時候需要依賴於 key。