使用MySQL 5.6 Memcache

4

我觉得我可能漏掉了一些非常显然的东西,但是我想做的是使用MySQL 5.6并通过memcache返回值。

所以,我已经设置了MYSQL来使用memcache插件,在innodb_memcache.containers表中设置了详细信息。

现在,该表中有两个条目,一个是MySQL输入的默认值,另一个是我自己的设置,它们都有表名。

为了通过php获得数据,我使用以下命令:

  $memcache->get($key);

其中$key是数据库列中的数据

然而这样返回了空值,我怀疑原因是,根据MySQL文档,如果没有指定表名,则会选择列表中的第一个表,而这不是我想要的表。我不明白的是,我如何在键中指定正确的表名,以便它知道在哪个表中查找该键。

附加信息:

table design:
    table: codes
    id INT PK
    code VARCHAR UNIQUE
    codeval VARCHAR


innodb_memcache.containers :
name: mycode
db_schema: databaseName
db_table: codes
key_columns: code
value_columns: codeval
flags: id
cas_column: null
expire_time_column: null
unique_idx_name_on_key: code

代码:

$table = "mycode";
$key = "123456";
 $memcache = new Memcache;
 $memcache->connect($this->CONNECTURL, $this->CONNECTPORT) or die ("Could not connect");
 $version = $memcache->getVersion();
  echo "Server's version: ".$version."<br/>\n";

 $key = "@@" . $table . "." . $key . "." . $table;
 $get_result = $memcache->get($key);

  print_r($get_result);

以上代码返回了服务器版本,说明连接正常。

print_r($get_result)应该返回一个值,但实际上是空的。

它会抛出一个警告:试图获取非对象属性。

因此,如果有人能告诉我如何使用$key指定我正在通过memcache查询的表,我将不胜感激!


要得到答案,您需要指定数据表结构、innodb_memcache.container 记录以及您打算如何从 Memcache 检索缓存数据($key 的确切值)。 - Mehran
我已经添加了额外的信息来帮助解决这个问题。 - Lawrence Cooke
4个回答

4

表名(在@@table_id中为table_id)必须是您的映射(innodb_memcache.containers)的值,而不是实际的表名(如果它有所变化)。

如果您在映射中的表名是mycode,那么通过memcache进行的查询应该是这样的:

$table = 'mycode';
$key   = '123456';
$memcache->get( '@@' . $table . '.' . $key );

结尾处不应有多余的'.' . $table

关于InnoDB memcached插件的详细信息可以在InnoDB memcached Plugin文档页面上找到。

以下是一些重要内容:

  1. 使用select * from innodb_memcache.containers;获取已定义的映射;
  2. 注意查询组织方式:

例如,@@t1.some_key和@@t2.some_key具有相同的键值, 但存储在不同的表中,因此不会冲突。


我知道这似乎是正确的事情,但我无法让它工作。我不知道哪里出了问题,按照所有步骤操作,仔细检查了你在这里写的内容,但它仍然没有任何反应。 - Lawrence Cooke

4

来源:http://dev.mysql.com/doc/refman/5.6/en/innodb-memcached-intro.html

命名空间:memcached就像一个单一的巨大目录,为了避免文件之间发生冲突,您可能会使用带有前缀和后缀的复杂名称。内置的InnoDB / memcached服务器让您使用这些相同的命名约定作为键名,但增加了一个附加项。格式为 @@table_id.key.table_id 的键名将被解码以引用特定的表,使用来自 innodb_memcache.containers 表的映射数据。该键将在指定的表中查找或写入。

@@符号仅适用于get,add和set函数的单个调用,而不适用于其他函数,如incr或delete。要指定默认表格以供会话中的所有后续memcached操作使用,请使用@@符号和表ID执行get请求,但不使用键部分。例如:

get @@ table_x

随后的get,set,incr,delete和其他操作使用 innodb_memcache.containers.name 列中指定的table_x。


0

如果您仍然使用默认表,可以尝试使用telnet。

注意:这是在具有memcached的AWS RDS实例上使用的,它应该对使用memcached的任何MySQL实现都是相同的,但我不确定。

telnet localhost 11211
stats
#=> should return a long list of stats including pid, uptime, etc

get AA
#=> should return
VALUE AA 8 12
HELLO, HELLO
END

quit #exit telnet session

我知道这并没有回答你的问题,但它可能有助于故障排除。


-2
<?php

$memc = new Memcache;
$memc->addServer('localhost','11211');

if(empty($_POST['film'])) {
?>
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <title>Simple Memcache Lookup</title>
    </head>
    <body>
      <form method="post">
        <p><b>Film</b>: <input type="text" size="20" name="film"></p>
        <input type="submit">
      </form>
      <hr/>
<?php

} else {

    echo "Loading data...\n";

    $film   = htmlspecialchars($_POST['film'], ENT_QUOTES, 'UTF-8');
    $mfilms = $memc->get($film);

    if ($mfilms) {

        printf("<p>Film data for %s loaded from memcache</p>", $mfilms['title']);

        foreach (array_keys($mfilms) as $key) {
            printf("<p><b>%s</b>: %s</p>", $key, $mfilms[$key]);
        }

    } else {

        $mysqli = mysqli('localhost','sakila','password','sakila');

        if (mysqli_connect_error()) {
            sprintf("Database error: (%d) %s", mysqli_connect_errno(), mysqli_connect_error());
            exit;
        }

        $sql = sprintf('SELECT * FROM film WHERE title="%s"', $mysqli->real_escape_string($film));

        $result = $mysqli->query($sql);

        if (!$result) {
            sprintf("Database error: (%d) %s", $mysqli->errno, $mysqli->error);
            exit;
        }

        $row = $result->fetch_assoc();

        $memc->set($row['title'], $row);

        printf("<p>Loaded (%s) from MySQL</p>", htmlspecialchars($row['title'], ENT_QUOTES, 'UTF-8');
    }
}
?>
  </body>
</html>

使用PHP时,只要PHP和相关的Apache实例保持运行状态,与memcached实例的连接就会保持打开状态。当在运行实例中添加或删除服务器列表(例如,启动另一个提及其他服务器的脚本时),连接是共享的,但脚本仅从脚本内明确配置的实例中进行选择。


谢谢您的回复,但它并没有真正回答我的问题。我的问题是,我正在尝试使用5.6中的新memcache层来查询数据库,但我无法弄清楚如何指定我输入的键应该查询哪个表。 - Lawrence Cooke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接