Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shard MySQL for connect four context #164

Merged
merged 21 commits into from
Apr 3, 2023

Conversation

marein
Copy link
Owner

@marein marein commented Mar 8, 2023

This pull requests applies schema-based sharding to the connect four context. It plays nicely with ProxySQL (which will be added for the prod example later). The env variable APP_CONNECT_FOUR_DOCTRINE_DBAL_URL needs to point to ProxySQL instead of MySQL, APP_CONNECT_FOUR_DOCTRINE_DBAL_SHARDS should define the logical shards and APP_CONNECT_FOUR_DOCTRINE_DBAL_DATABASE needs to point to the first shard. The following ProxySQL service definition routes 3 logical shards to 2 physical shards once #167 is merged.

Show code
proxysql:
    image: marein/php-gaming-website:proxysql
    environment:
        PROXYSQL_CONFIG: |
            admin_variables: {
                restapi_enabled="true"
            }
            mysql_variables: {
                server_version="8.0"
                monitor_username="root"
                monitor_password="password"
                auto_increment_delay_multiplex=0
            }
            mysql_servers: (
                {hostgroup=1,address="mysql-1",port=3306,max_connections=100},
                {hostgroup=2,address="mysql-2",port=3306,max_connections=100}
            )
            mysql_users: (
                {username="root",password="password",default_hostgroup=1}
            )
            mysql_query_rules: (
                {rule_id=1,schemaname="connect-four-shard1",destination_hostgroup=1,apply=1},
                {rule_id=2,schemaname="connect-four-shard2",destination_hostgroup=2,apply=1},
                {rule_id=3,schemaname="connect-four-shard3",destination_hostgroup=1,apply=1},
                {rule_id=4,match_pattern="^CREATE DATABASE(?: IF NOT EXISTS)? `connect-four-shard1`$",replace_pattern="CREATE DATABASE IF NOT EXISTS `connect-four-shard1`",destination_hostgroup=1,apply=1},
                {rule_id=5,match_pattern="^CREATE DATABASE(?: IF NOT EXISTS)? `connect-four-shard2`$",replace_pattern="CREATE DATABASE IF NOT EXISTS `connect-four-shard2`",destination_hostgroup=2,apply=1},
                {rule_id=6,match_pattern="^CREATE DATABASE(?: IF NOT EXISTS)? `connect-four-shard3`$",replace_pattern="CREATE DATABASE IF NOT EXISTS `connect-four-shard3`",destination_hostgroup=1,apply=1}
            )
    depends_on:
        - mysql-1
        - mysql-2

Tested with 3 physical MySQL shards and ProxySQL deployed as a sidecar of the app. The test was running for 10 minutes with a constant throughput of 25k write requests / s. The load was well distributed.

This pull request doesn't take resharding into consideration.

* Apply schema based sharding
The shard is determined by a modulo operation.
* Make database name configurable via env variable
Doctrine commands aren't accepting a database name as a cli
argument. By overwriting the env variable, see entrypoint,
we can change the database without changing the whole connection
string.
* Acceptance tests are disabled for now
This reason is that the number of shards isn't yet configurable.
@marein marein self-assigned this Mar 8, 2023
@marein marein marked this pull request as draft March 8, 2023 21:25
@marein marein linked an issue Mar 8, 2023 that may be closed by this pull request
bin/connect-four/onEntrypoint Outdated Show resolved Hide resolved
* Besides the repository, the event store access must also be
sharding aware, since this is read when the query model is not
yet populated. For that matter, to query the events from the
write model, the repository is used, which encapsulates the
event store. Additionally, the event store is used directly
for appending events.
* Introduce ShardChooser
ShardChooser encapsulates the logic of selecting a shard.
* Remove query model's GameNotFoundException
This is an aside refactoring, not related. This indirection
isn't needed.
@marein marein force-pushed the 119-shard-mysql-for-connect-four-context branch from e9eda23 to 39776f3 Compare March 11, 2023 15:13
@marein marein marked this pull request as ready for review March 11, 2023 23:35
@marein marein force-pushed the 119-shard-mysql-for-connect-four-context branch from c835b93 to e46806c Compare March 14, 2023 22:28
@marein marein mentioned this pull request Mar 18, 2023
They don't relate to this changes and
might come in another pull request.
@marein marein force-pushed the 119-shard-mysql-for-connect-four-context branch from 36fbfa2 to cfd9adc Compare March 29, 2023 16:04
That didn't belong there and was just a quick
implementation to serve the query model handler.
@marein marein force-pushed the 119-shard-mysql-for-connect-four-context branch from 7644a78 to c4860fd Compare March 29, 2023 18:48
@marein marein force-pushed the 119-shard-mysql-for-connect-four-context branch from 5ead3a5 to e5130e8 Compare March 31, 2023 15:49
@marein marein merged commit 805c240 into master Apr 3, 2023
@marein marein deleted the 119-shard-mysql-for-connect-four-context branch April 3, 2023 10:51
marein added a commit that referenced this pull request Apr 3, 2023
Applies schema-based sharding for the connect four database #119.
The application itself only knows about logical shards and relies
on a proxy, such as ProxySQL, to forward queries to physical shards.

* The env variable APP_CONNECT_FOUR_DOCTRINE_DBAL_SHARDS
defines a comma-separated list of active shards. As games can
be sharded across multiple physical databases, the transactional scope
(technical-wise) is moved to the repository layer, and removed from the
application layer. The changes to the repository, which is now very
persistence oriented, aim to make this explicit. The shard selection
happens based on the game id.
* The env variable APP_CONNECT_FOUR_DOCTRINE_DBAL_DATABASE
is introduced to allow selecting a shard for database creation and
migration, as doctrine commands currently don't allow passing
the database name via cli arguments.
* Besides the repository, the event store access must also be
aware of sharding, since this is read when the query model is not
yet populated. For that matter, to query the events from the
write model, the repository is used, which encapsulates the
EventStore.
* Remove query model's GameNotFoundException
This is an aside refactoring, not related. This indirection
wasn't needed in the past. Additionally, an instance of
GameId is required to find a game, not a loose string.
* The current implementation doesn't take resharding into
consideration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Shard MySQL for connect four context
1 participant