1DBIx::Class::Storage::DUBsIeD:rB:IRCxeo:pn:ltCirlciaabstuset:de::dS:tIPonertrarlgoedD:uo:ccDtuBimIoe:nn:(tR3ae)tpiloincated::Introduction(3)
2
3
4
6 DBIx::Class::Storage::DBI::Replicated::Introduction - Minimum Need to
7 Know
8
10 This is an introductory document for DBIx::Class::Storage::Replication.
11
12 This document is not an overview of what replication is or why you
13 should be using it. It is not a document explaining how to setup MySQL
14 native replication either. Copious external resources are available
15 for both. This document presumes you have the basics down.
16
18 DBIx::Class supports a framework for using database replication. This
19 system is integrated completely, which means once it's setup you should
20 be able to automatically just start using a replication cluster without
21 additional work or changes to your code. Some caveats apply, primarily
22 related to the proper use of transactions (you are wrapping all your
23 database modifying statements inside a transaction, right ;) ) however
24 in our experience properly written DBIC will work transparently with
25 Replicated storage.
26
27 Currently we have support for MySQL native replication, which is
28 relatively easy to install and configure. We also currently support
29 single master to one or more replicants (also called 'slaves' in some
30 documentation). However the framework is not specifically tied to the
31 MySQL framework and supporting other replication systems or
32 topographies should be possible. Please bring your patches and ideas
33 to the #dbix-class IRC channel or the mailing list.
34
35 For an easy way to start playing with MySQL native replication, see:
36 MySQL::Sandbox.
37
38 If you are using this with a Catalyst based application, you may also
39 want to see more recent updates to Catalyst::Model::DBIC::Schema, which
40 has support for replication configuration options as well.
41
43 By default, when you start DBIx::Class, your Schema
44 (DBIx::Class::Schema) is assigned a storage_type, which when fully
45 connected will reflect your underlying storage engine as defined by
46 your chosen database driver. For example, if you connect to a MySQL
47 database, your storage_type will be DBIx::Class::Storage::DBI::mysql
48 Your storage type class will contain database specific code to help
49 smooth over the differences between databases and let DBIx::Class do
50 its thing.
51
52 If you want to use replication, you will override this setting so that
53 the replicated storage engine will 'wrap' your underlying storages and
54 present a unified interface to the end programmer. This wrapper
55 storage class will delegate method calls to either a master database or
56 one or more replicated databases based on if they are read only (by
57 default sent to the replicants) or write (reserved for the master).
58 Additionally, the Replicated storage will monitor the health of your
59 replicants and automatically drop them should one exceed configurable
60 parameters. Later, it can automatically restore a replicant when its
61 health is restored.
62
63 This gives you a very robust system, since you can add or drop
64 replicants and DBIC will automatically adjust itself accordingly.
65
66 Additionally, if you need high data integrity, such as when you are
67 executing a transaction, replicated storage will automatically delegate
68 all database traffic to the master storage. There are several ways to
69 enable this high integrity mode, but wrapping your statements inside a
70 transaction is the easy and canonical option.
71
73 A replicated storage contains several parts. First, there is the
74 replicated storage itself (DBIx::Class::Storage::DBI::Replicated). A
75 replicated storage takes a pool of replicants
76 (DBIx::Class::Storage::DBI::Replicated::Pool) and a software balancer
77 (DBIx::Class::Storage::DBI::Replicated::Pool). The balancer does the
78 job of splitting up all the read traffic amongst the replicants in the
79 Pool. Currently there are two types of balancers, a Random one which
80 chooses a Replicant in the Pool using a naive randomizer algorithm, and
81 a First replicant, which just uses the first one in the Pool (and
82 obviously is only of value when you have a single replicant).
83
85 All the parts of replication can be altered dynamically at runtime,
86 which makes it possibly to create a system that automatically scales
87 under load by creating more replicants as needed, perhaps using a cloud
88 system such as Amazon EC2. However, for common use you can setup your
89 replicated storage to be enabled at the time you connect the databases.
90 The following is a breakdown of how you may wish to do this. Again, if
91 you are using Catalyst, I strongly recommend you use (or upgrade to)
92 the latest Catalyst::Model::DBIC::Schema, which makes this job even
93 easier.
94
95 First, you need to get a $schema object and set the storage_type:
96
97 my $schema = MyApp::Schema->clone;
98 $schema->storage_type([
99 '::DBI::Replicated' => {
100 balancer_type => '::Random',
101 balancer_args => {
102 auto_validate_every => 5,
103 master_read_weight => 1
104 },
105 pool_args => {
106 maximum_lag =>2,
107 },
108 }
109 ]);
110
111 Then, you need to connect your DBIx::Class::Schema.
112
113 $schema->connection($dsn, $user, $pass);
114
115 Let's break down the settings. The method "storage_type" in
116 DBIx::Class::Schema takes one mandatory parameter, a scalar value, and
117 an option second value which is a Hash Reference of configuration
118 options for that storage. In this case, we are setting the Replicated
119 storage type using '::DBI::Replicated' as the first value. You will
120 only use a different value if you are subclassing the replicated
121 storage, so for now just copy that first parameter.
122
123 The second parameter contains a hash reference of stuff that gets
124 passed to the replicated storage. "balancer_type" in
125 DBIx::Class::Storage::DBI::Replicated is the type of software load
126 balancer you will use to split up traffic among all your replicants.
127 Right now we have two options, "::Random" and "::First". You can review
128 documentation for both at:
129
130 DBIx::Class::Storage::DBI::Replicated::Balancer::First,
131 DBIx::Class::Storage::DBI::Replicated::Balancer::Random.
132
133 In this case we will have three replicants, so the ::Random option is
134 the only one that makes sense.
135
136 'balancer_args' get passed to the balancer when it's instantiated. All
137 balancers have the 'auto_validate_every' option. This is the number of
138 seconds we allow to pass between validation checks on a load balanced
139 replicant. So the higher the number, the more possibility that your
140 reads to the replicant may be inconsistent with what's on the master.
141 Setting this number too low will result in increased database loads, so
142 choose a number with care. Our experience is that setting the number
143 around 5 seconds results in a good performance / integrity balance.
144
145 'master_read_weight' is an option associated with the ::Random
146 balancer. It allows you to let the master be read from. I usually
147 leave this off (default is off).
148
149 The 'pool_args' are configuration options associated with the replicant
150 pool. This object (DBIx::Class::Storage::DBI::Replicated::Pool)
151 manages all the declared replicants. 'maximum_lag' is the number of
152 seconds a replicant is allowed to lag behind the master before being
153 temporarily removed from the pool. Keep in mind that the Balancer
154 option 'auto_validate_every' determines how often a replicant is tested
155 against this condition, so the true possible lag can be higher than the
156 number you set. The default is zero.
157
158 No matter how low you set the maximum_lag or the auto_validate_every
159 settings, there is always the chance that your replicants will lag a
160 bit behind the master for the supported replication system built into
161 MySQL. You can ensure reliable reads by using a transaction, which
162 will force both read and write activity to the master, however this
163 will increase the load on your master database.
164
165 After you've configured the replicated storage, you need to add the
166 connection information for the replicants:
167
168 $schema->storage->connect_replicants(
169 [$dsn1, $user, $pass, \%opts],
170 [$dsn2, $user, $pass, \%opts],
171 [$dsn3, $user, $pass, \%opts],
172 );
173
174 These replicants should be configured as slaves to the master using the
175 instructions for MySQL native replication, or if you are just learning,
176 you will find MySQL::Sandbox an easy way to set up a replication
177 cluster.
178
179 And now your $schema object is properly configured! Enjoy!
180
182 John Napiorkowski <jjnapiork@cpan.org>
183
185 You may distribute this code under the same terms as Perl itself.
186
187
188
189perl v5.12.0 DBIx::Clas2s0:1:0S-t0o5r-a1g2e::DBI::Replicated::Introduction(3)