mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-16 00:48:54 +00:00
Cache integration examples
git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@324246 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
parent
902cbcc2df
commit
18ac0c56e9
1 changed files with 200 additions and 0 deletions
|
@ -1510,6 +1510,206 @@ var_dump($res->fetch_assoc());
|
|||
</example>
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="mysqlnd-ms.quickstart.cache">
|
||||
<title>Cache integration</title>
|
||||
<note>
|
||||
<title>Version requirement and dependencies</title>
|
||||
<para>
|
||||
Cache integration is available as of PECL/mysqlnd_ms 1.3.0-beta (under development).
|
||||
PECL/mysqlnd_qc 1.1.0 (under development) or newer is used as a cache. Both plugins
|
||||
must be installed. PECL/mysqlnd_ms must be compiled to support the cache feature.
|
||||
Use of PHP 5.4.0 or newer is mandatory.
|
||||
</para>
|
||||
</note>
|
||||
<para>
|
||||
Databases clusters can deliver different levels of consistency. As of
|
||||
PECL/mysqlnd_ms 1.2.0 it is possible to advice the plugin to consider only
|
||||
cluster nodes that can deliver the consistency level requested. For example,
|
||||
if using asynchronous MySQL Replication with its cluster-wide eventual
|
||||
consistency, it is possible to request session consistency (read your writes)
|
||||
at any time using <function>mysqlnd_ms_set_quos</function>. Please, see also the
|
||||
<link linkend="mysqlnd-ms.quickstart.qos-consistency">service level and consistency</link>
|
||||
introduction.
|
||||
</para>
|
||||
<para>
|
||||
<example>
|
||||
<title>Recap: quality of service to request read your writes</title>
|
||||
<programlisting role="php">
|
||||
/* Request session consistency: read your writes */
|
||||
if (!mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_SESSION))
|
||||
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
|
||||
</programlisting>
|
||||
</example>
|
||||
</para>
|
||||
<para>
|
||||
Assuming PECL/mysqlnd has been explicitly told to deliver no consistency level
|
||||
higher than eventual consistency, it is possible to replace a database node
|
||||
read access with a client-side cache using time-to-live (TTL) as its invalidation
|
||||
strategy. Both the database node and the cache may or may not serve
|
||||
current data as this is what eventual consistency defines.
|
||||
</para>
|
||||
<para>
|
||||
Replacing a database node read access with a local cache access can improve
|
||||
overall performance and lower the database load. If the cache entry is every
|
||||
reused by other clients than the one creating the cache entry,
|
||||
a database access is saved and thus database load is lowered. Furthermore,
|
||||
system performance can become better if computation and delivery
|
||||
of a database query is slower than a local cache access.
|
||||
</para>
|
||||
<para>
|
||||
<example>
|
||||
<title>Plugin config: no special entries for caching</title>
|
||||
<programlisting role="ini">
|
||||
<![CDATA[
|
||||
{
|
||||
"myapp": {
|
||||
"master": {
|
||||
"master_0": {
|
||||
"host": "localhost",
|
||||
"socket": "\/tmp\/mysql.sock"
|
||||
}
|
||||
},
|
||||
"slave": {
|
||||
"slave_0": {
|
||||
"host": "127.0.0.1",
|
||||
"port": "3306"
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</programlisting>
|
||||
</example>
|
||||
</para>
|
||||
<para>
|
||||
<example>
|
||||
<title>Caching a slave request</title>
|
||||
<programlisting role="php">
|
||||
<![CDATA[
|
||||
<?php
|
||||
$mysqli = new mysqli("myapp", "username", "password", "database");
|
||||
if (!$mysqli)
|
||||
/* Of course, your error handling is nicer... */
|
||||
die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));
|
||||
|
||||
if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
|
||||
!$mysqli->query("CREATE TABLE test(id INT)") ||
|
||||
!$mysqli->query("INSERT INTO test(id) VALUES (1)"))
|
||||
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
|
||||
|
||||
/* Explicitly allow eventual consistency and caching (TTL <= 60 seconds) */
|
||||
if (false == mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL, MYSQLND_MS_QOS_OPTION_CACHE, 60)) {
|
||||
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
|
||||
}
|
||||
|
||||
/* To make this example work, we must wait for a slave to catch up. Brute force style. */
|
||||
$attempts = 0;
|
||||
do {
|
||||
/* check if slave has the table */
|
||||
if ($res = $mysqli->query("SELECT id FROM test")) {
|
||||
break;
|
||||
} else if ($mysqli->errno) {
|
||||
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
|
||||
}
|
||||
/* wait for slave to catch up */
|
||||
usleep(200000);
|
||||
} while ($attempts++ < 10);
|
||||
|
||||
/* Query has been run on a slave, result is in the cache */
|
||||
assert($res);
|
||||
var_dump($res->fetch_assoc());
|
||||
|
||||
/* Served from cache */
|
||||
$res = $mysqli->query("SELECT id FROM test");
|
||||
?>
|
||||
]]>
|
||||
</programlisting>
|
||||
</example>
|
||||
</para>
|
||||
<para>
|
||||
The example shows how to use the cache feature. First, you have to set
|
||||
the quality of service to eventual consistency and explicitly allow for caching.
|
||||
This is done by calling <function>mysqlnd_ms_set_qos</function>.
|
||||
Then, the result set of every read-only statement is cached for upto that
|
||||
many seconds as allowed with <function>mysqlnd_ms_set_qos</function>.
|
||||
</para>
|
||||
<para>
|
||||
The actual TTL is lower or equal to the value set
|
||||
with <function>mysqlnd_ms_set_qos</function>. The value passed to the
|
||||
function sets the maximum age (seconds) of the data delivered. To calculate
|
||||
the actual TTL value the replication lag on a slave is checked and substracted
|
||||
from the given value. If, for example, the maximum age is set to 60 seconds and
|
||||
the slave reports a lag of 10 seconds the resulting TTL is 50 seconds.
|
||||
The TTL is calculated individually for every cached query.
|
||||
</para>
|
||||
<para>
|
||||
<example>
|
||||
<title>Read your writes and caching combined</title>
|
||||
<programlisting role="php">
|
||||
<![CDATA[
|
||||
<?php
|
||||
$mysqli = new mysqli("myapp", "username", "password", "database");
|
||||
if (!$mysqli)
|
||||
/* Of course, your error handling is nicer... */
|
||||
die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));
|
||||
|
||||
if (!$mysqli->query("DROP TABLE IF EXISTS test") ||
|
||||
!$mysqli->query("CREATE TABLE test(id INT)") ||
|
||||
!$mysqli->query("INSERT INTO test(id) VALUES (1)"))
|
||||
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
|
||||
|
||||
/* Explicitly allow eventual consistency and caching (TTL <= 60 seconds) */
|
||||
if (false == mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL, MYSQLND_MS_QOS_OPTION_CACHE, 60)) {
|
||||
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
|
||||
}
|
||||
|
||||
/* To make this example work, we must wait for a slave to catch up. Brute force style. */
|
||||
$attempts = 0;
|
||||
do {
|
||||
/* check if slave has the table */
|
||||
if ($res = $mysqli->query("SELECT id FROM test")) {
|
||||
break;
|
||||
} else if ($mysqli->errno) {
|
||||
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
|
||||
}
|
||||
/* wait for slave to catch up */
|
||||
usleep(200000);
|
||||
} while ($attempts++ < 10);
|
||||
|
||||
assert($res);
|
||||
|
||||
/* Query has been run on a slave, result is in the cache */
|
||||
var_dump($res->fetch_assoc());
|
||||
|
||||
/* Served from cache */
|
||||
if (!($res = $mysqli->query("SELECT id FROM test")))
|
||||
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
|
||||
var_dump($res->fetch_assoc());
|
||||
|
||||
/* Update on master */
|
||||
if (!$mysqli->query("UPDATE test SET id = 2"))
|
||||
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
|
||||
|
||||
/* Read your writes */
|
||||
if (false == mysqlnd_ms_set_qos($mysqli, MYSQLND_MS_QOS_CONSISTENCY_SESSION)) {
|
||||
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
|
||||
}
|
||||
|
||||
/* Fetch latest data */
|
||||
if (!($res = $mysqli->query("SELECT id FROM test")))
|
||||
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
|
||||
var_dump($res->fetch_assoc());
|
||||
?>
|
||||
]]>
|
||||
</programlisting>
|
||||
</example>
|
||||
</para>
|
||||
<para>
|
||||
The quality of service can be changed at any time to avoid further cache usage.
|
||||
If needed, you can switch to read your writes (session consistency). In that case,
|
||||
the cache will not be used and fresh data is read.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
|
|
Loading…
Reference in a new issue