Package com.linkedin.venice.listener
Class StoreValueSchemasCacheService
- java.lang.Object
-
- com.linkedin.venice.service.AbstractVeniceService
-
- com.linkedin.venice.listener.StoreValueSchemasCacheService
-
- All Implemented Interfaces:
ReadOnlySchemaRepository
,VeniceResource
,java.io.Closeable
,java.lang.AutoCloseable
public class StoreValueSchemasCacheService extends AbstractVeniceService implements ReadOnlySchemaRepository
This class implements the fast value schema/latest value schema lookup with acceptable delay. The reason to introduce this class is that we found two issues to useHelixReadOnlySchemaRepository
directly in read compute path: 1. When ZK disconnect/re-connect happens,HelixReadOnlySchemaRepository
will refresh its local cache, which would cause an increased GC count in read compute sinceHelixReadOnlySchemaRepository.refresh()
is holding a giant write lock and all the value schema/latest value schema lookups in the read compute requests will be blocked. The GC count increase is significant (more than doubled in test cluster), which has been causing much higher CPU usage and higher latency; 2. The schema objects returned byHelixReadOnlySchemaRepository
for the same schema are not always the same object sinceHelixReadOnlySchemaRepository.refresh()
would always re-create new Schema objects, which will cause the inefficient de-serializer lookup inSerializerDeserializerFactory
, which will compare the schema objects to find out the corresponding serializer/de-serializer (for read compute case, de-serializer is the concern). If the schema objects are not the same,Schema.hashCode()
andSchema.equals(Object)
will be used, in Avro-1.7 or above,Schema.hashCode()
is optimized to only calculate once if it is read-only, butSchema.equals(Object)
couldn't be avoided. Here how it works in this class: 1. It maintains a mapping between stores and their value schemas and latest value schema; 2. It will try to reuse the sameSchema
object for the same Schema Id within a store since value schema is immutable; 3. It maintains a refresh thread to update the local cache periodically; In theory, all the schema lookups shouldn't be blocked by invoking the underlyingHelixReadOnlySchemaRepository
since in reality, it will take a fair long time to register a new value schema/latest value schema and start using it in prod, so the periodical schema refresh should be able to take care of the new value schema/latest value schema discovery. Since the refresh is async, there is a delay there (at most 1 min), and it should be acceptable because of the previous assumption. So far, this class only supports value schema by id lookup and latest value schema lookup.
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from class com.linkedin.venice.service.AbstractVeniceService
AbstractVeniceService.ServiceState
-
-
Field Summary
-
Fields inherited from class com.linkedin.venice.service.AbstractVeniceService
logger, serviceState
-
-
Constructor Summary
Constructors Constructor Description StoreValueSchemasCacheService(ReadOnlyStoreRepository storeRepository, ReadOnlySchemaRepository schemaRepository)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
clear()
DerivedSchemaEntry
getDerivedSchema(java.lang.String storeName, int valueSchemaId, int derivedSchemaId)
GeneratedSchemaID
getDerivedSchemaId(java.lang.String storeName, java.lang.String derivedSchemaStr)
Look up derived schema id and its corresponding value schema id by given store name and derived schema.java.util.Collection<DerivedSchemaEntry>
getDerivedSchemas(java.lang.String storeName)
SchemaEntry
getKeySchema(java.lang.String storeName)
Get key schema for the given store.DerivedSchemaEntry
getLatestDerivedSchema(java.lang.String storeName, int valueSchemaId)
Get the most recent derived schema added to the given store and value schema idRmdSchemaEntry
getReplicationMetadataSchema(java.lang.String storeName, int valueSchemaId, int replicationMetadataVersionId)
java.util.Collection<RmdSchemaEntry>
getReplicationMetadataSchemas(java.lang.String storeName)
SchemaEntry
getSupersetOrLatestValueSchema(java.lang.String storeName)
Get the most recent value schema or superset value schema if one exists.SchemaEntry
getSupersetSchema(java.lang.String storeName)
Get the superset value schema for a given store.SchemaEntry
getValueSchema(java.lang.String storeName, int valueSchemaId)
Get value schema for the given store and value schema id.int
getValueSchemaId(java.lang.String storeName, java.lang.String valueSchemaStr)
Return the schema ID of any schema for the store that has the same parsing canonical form as the schema provided.java.util.Collection<SchemaEntry>
getValueSchemas(java.lang.String storeName)
Get all the value schemas for the given store.boolean
hasValueSchema(java.lang.String storeName, int id)
Check whether the specified schema id is valid or notvoid
refresh()
boolean
startInner()
void
stopInner()
-
Methods inherited from class com.linkedin.venice.service.AbstractVeniceService
close, getName, isRunning, start, stop
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface com.linkedin.venice.meta.ReadOnlySchemaRepository
getLatestDerivedSchema
-
-
-
-
Constructor Detail
-
StoreValueSchemasCacheService
public StoreValueSchemasCacheService(ReadOnlyStoreRepository storeRepository, ReadOnlySchemaRepository schemaRepository)
-
-
Method Detail
-
startInner
public boolean startInner() throws java.lang.Exception
- Specified by:
startInner
in classAbstractVeniceService
- Returns:
- true if the service is completely started,
false if it is still starting asynchronously (in this case, it is the implementer's
responsibility to set
AbstractVeniceService.serviceState
toAbstractVeniceService.ServiceState.STARTED
upon completion of the async work). - Throws:
java.lang.Exception
-
stopInner
public void stopInner() throws java.lang.Exception
- Specified by:
stopInner
in classAbstractVeniceService
- Throws:
java.lang.Exception
-
getValueSchema
public SchemaEntry getValueSchema(java.lang.String storeName, int valueSchemaId)
Description copied from interface:ReadOnlySchemaRepository
Get value schema for the given store and value schema id.- Specified by:
getValueSchema
in interfaceReadOnlySchemaRepository
-
getSupersetOrLatestValueSchema
public SchemaEntry getSupersetOrLatestValueSchema(java.lang.String storeName)
Description copied from interface:ReadOnlySchemaRepository
Get the most recent value schema or superset value schema if one exists.- Specified by:
getSupersetOrLatestValueSchema
in interfaceReadOnlySchemaRepository
-
getSupersetSchema
public SchemaEntry getSupersetSchema(java.lang.String storeName)
Description copied from interface:ReadOnlySchemaRepository
Get the superset value schema for a given store. Each store has at most one active superset schema. Specifically a store must have some features enabled (e.g. read compute, write compute) to have a superset value schema which evolves as new value schemas are added.- Specified by:
getSupersetSchema
in interfaceReadOnlySchemaRepository
- Returns:
- Superset value schema or
null
if store {@param storeName} does not have any superset value schema.
-
getKeySchema
public SchemaEntry getKeySchema(java.lang.String storeName)
Description copied from interface:ReadOnlySchemaRepository
Get key schema for the given store.- Specified by:
getKeySchema
in interfaceReadOnlySchemaRepository
-
hasValueSchema
public boolean hasValueSchema(java.lang.String storeName, int id)
Description copied from interface:ReadOnlySchemaRepository
Check whether the specified schema id is valid or not- Specified by:
hasValueSchema
in interfaceReadOnlySchemaRepository
-
getValueSchemaId
public int getValueSchemaId(java.lang.String storeName, java.lang.String valueSchemaStr)
Description copied from interface:ReadOnlySchemaRepository
Return the schema ID of any schema for the store that has the same parsing canonical form as the schema provided.- Specified by:
getValueSchemaId
in interfaceReadOnlySchemaRepository
-
getValueSchemas
public java.util.Collection<SchemaEntry> getValueSchemas(java.lang.String storeName)
Description copied from interface:ReadOnlySchemaRepository
Get all the value schemas for the given store.- Specified by:
getValueSchemas
in interfaceReadOnlySchemaRepository
-
getDerivedSchemaId
public GeneratedSchemaID getDerivedSchemaId(java.lang.String storeName, java.lang.String derivedSchemaStr)
Description copied from interface:ReadOnlySchemaRepository
Look up derived schema id and its corresponding value schema id by given store name and derived schema. This is likely used by clients that write to Venice- Specified by:
getDerivedSchemaId
in interfaceReadOnlySchemaRepository
- Returns:
- a pair where the first value is value schema id and the second value is derived schema id
-
getDerivedSchema
public DerivedSchemaEntry getDerivedSchema(java.lang.String storeName, int valueSchemaId, int derivedSchemaId)
- Specified by:
getDerivedSchema
in interfaceReadOnlySchemaRepository
-
getDerivedSchemas
public java.util.Collection<DerivedSchemaEntry> getDerivedSchemas(java.lang.String storeName)
- Specified by:
getDerivedSchemas
in interfaceReadOnlySchemaRepository
-
getLatestDerivedSchema
public DerivedSchemaEntry getLatestDerivedSchema(java.lang.String storeName, int valueSchemaId)
Description copied from interface:ReadOnlySchemaRepository
Get the most recent derived schema added to the given store and value schema id- Specified by:
getLatestDerivedSchema
in interfaceReadOnlySchemaRepository
-
getReplicationMetadataSchema
public RmdSchemaEntry getReplicationMetadataSchema(java.lang.String storeName, int valueSchemaId, int replicationMetadataVersionId)
- Specified by:
getReplicationMetadataSchema
in interfaceReadOnlySchemaRepository
-
getReplicationMetadataSchemas
public java.util.Collection<RmdSchemaEntry> getReplicationMetadataSchemas(java.lang.String storeName)
- Specified by:
getReplicationMetadataSchemas
in interfaceReadOnlySchemaRepository
-
refresh
public void refresh()
- Specified by:
refresh
in interfaceVeniceResource
-
clear
public void clear()
- Specified by:
clear
in interfaceVeniceResource
-
-