- Notifications
You must be signed in to change notification settings - Fork62
A bundle for implementing application level sharding on traditional databases.
License
santanusinha/dropwizard-db-sharding-bundle
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Application level sharding for traditional relational databases.Apache Licensed
Principle: Evenly distribute data irrespective of actual number of physical shards chosen by application owners.
Strategy:
- Pick a hashing algorithm with good distribution characteristics for most inputs.
- Pick a large bucket size. Sharding key will be hashed to one of these buckets as a first step.
- Using a large bucket size is expected to distribute keys fairly evenly. Buckets are grouped together to form intervalswith each interval mapping to a physical shard.This bucket to shard mapping is created at application startup time.
For purpose of evenly distributing data, a hashing algorithm is used to hash a key to one of a large number ofbuckets.Current bucket size is1024.
For Bucket count K, and Physical shards N, usually K >> N. Buckets are divided into intervals of size N/K and eachinterval is mapped one-to-one to a physical shard.
Hashing.murmur3_128() from Guava library is used which yields a 128 bit value corresponding to the hashing key.This value is converted to integer to get bucket and in turn physical shard to which value for the key will be saved andretrieved.
What happens if an application owner decides to change the number of physical shards. For example from 16 to 32.
Resharding will be required to persist data to its new shard.
Daos are supposed to be objects to interact with datasource.Dao classes in db sharding bundle are a layer above Hibernate. Daos interact with database via Hibernate session.
- A dao used to work with entities related to a parent shard. The parent may or maynot be physically present.
- A murmur 128 hash of the string parent key is used to route the save and retrieve calls from the proper shard.
- A dao to save and retrieve top level entities in the system.
- Entity persisted using LookupDao needs to have exactly one field annotated with @LookupKey. This field willbe used as sharding key and hashed to right shard by same logic explained above.
- A read-through/write-through wrapper over LookupDao.
- It has a simple cache interface
LookupCachewith essential methods. - Any custom cache implementation can be used to implement this cache and initialize
CacheableLookupDaoeg.Caffeine/Guava cache.
- A read-through/write-through wrapper over RelationalDao.
- It has a simple cache interface
RelationalCachewith more methods compared to LookupCache. - Any custom cache implementation can be used to implement this cache and initialize
CacheableRelationalDaoeg.Caffeine/Guava cache.
If both RelationalDao and LookupDao use same logic of sharding based on a key, what is the difference between these two DAOs?
When to use which one?This can be slightly confusing to a beginner!RelationalDao is right choice for all entities that can be seen as children of same parent. While LookupDaois right choice for an entity that doesn't seem to have parent-child relationship or sibling relationship with any otherentity.
Example - If merchant is considered as parent entity, all entities such as merchant payment options,merchant attributes, merchant preference info can be treated as children of this parent entity and persistedusing a RelationalDao. Using a relational dao indicates that these entities are related and should be colocatedon same shard to enable join/subselect queries etc.
But, another entity such as Agent table, which keeps info of agents who work on acquiring or helping multiple merchants,and are not relatedto any other entity in merchant database, may use a LookupDao, since it is a TOP-LEVEL entity in the system.
One of the main requirements of sharding relational data is to colocate data for entities that might beaccessed or retrived together. For example, a merchant's profile, her store information, her payment options might bepulled togetherin some flows, so it should be located on the same shard for a merchant M.For this purpose, shard containing merchant M's primary profile info can be considered as parent shard and merchant's Idcan be treated as parent key.This parent key can be used for persisting related entities for the merchant using Relational Dao.
Only for related entities, it makes sense to pick and use same parent key.
Sharding key is required to shard an entity's data among different shards, it may have no relation in generalwith any other entity. But, mostly entities are related to each other, so picking one sharding key/parent keyto persist a number of related entities helps to keep code predictable and maintainable.
LookupDao can be used for this purpose. Unlike RelationalDao, LookupDao has the concept of LookupKey.One of the fields in the entity can be annotated with @LookupKey annotation to use this field for saving and retrievingentity. This field will be treated as hashing key with the Dao.
It is possible sometimes that one or more shards go bad due to a hardware or connectivity issue.In that situation, that shard can be blacklisted, to keep service operational while shard is fixedor shard endpoint is changed.
ShardBlacklistingStore is an interface, which contains methods to:
- blacklist a shard
- unblacklist a shard
- check if a shard is blacklisted
Since this library bundle will be part of an application with multiple boxes, it will beeasier to implementShardBlacklistingStore as integration with a distributed cache or designated service whichwill keep account of currently blacklisted shards for your backend service.
Pagination support
Hibernate framework has in-built support for pagination. DBShardingBundle has wrapper methods which internally call pagination-supporting hibernate apis such as list(Criteria) Example - public List<T> select(String parentKey, DetachedCriteria criteria, int first, int numResults) throws Exception;Updating multiple rows at once - TBD
Please refer test classes to understand sample usage of daos.
The project dependencies are:
<dependency> <groupId>io.appform.dropwizard.sharding</groupId> <artifactId>db-sharding-bundle</artifactId> <version>2.1.10-11</version></dependency>Set the Number of Shards property by setting Java property while starting the application.
- Initiating Sharding Bundle with namespace
BalancedDBShardingBundle<Configuration> dbShardingBundle = new BalancedDBShardingBundle<Configuration>( "your_namespace", // This is optional List.of("com.example.server.core.entities") ) { @Override protected ShardedHibernateFactory getConfig(Configuration appConfig) { return appConfig.getShards(); } };While running your application, ensure to set-Dyour_namespace.db.shards=32 property. By defaultdb.shards=2
- Package and group id has changed from
io.dropwizard.shardingtoio.appfrom.dropwizard.shardingfrom 1.3.12-3. - static create* methods have been replaced with instance methods from 1.3.13-4
- Java compatibility moved to 11 (-release 11) from 2.1.10-1 onwards
About
A bundle for implementing application level sharding on traditional databases.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
