4

我认为我必须在这里遗漏一些非常明显的东西,但我想做的是使用 MySQL 5.6 并通过 memcache 返回值

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

我现在在那个表中有两个项目,MySQL 输入的默认项目和我自己的设置,它们都有表名。

要通过 php 获取数据,我使用:

  $memcache->get($key);

其中 $key 是 db 列中的数据

但是这什么也没返回,我怀疑原因是,根据 MySQL Docs 如果没有指定表名,它会选择列表中的第一个,这不是我想要的,我不明白我是如何在键中指定正确的表名,因此它知道要在哪个表中查找键。

附加信息:

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 查询的表,我将不胜感激!

4

4 回答 4

4

表名 ( table_idin @@table_id) 必须是映射 ( innodb_memcache.containers) 中的值,而不是实际表名(如果有所不同)。

如果你在 mappings 中的表名是mycode,那么通过memcache得到的查询应该是这样的:

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

最后没有多余'.' . $table的。

InnoDB memcached Plugin文档页面提供了一些详细信息。

在这里举几个重要的例子:

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

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

于 2013-07-10T08:48:42.303 回答
4

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

命名空间:memcached 就像一个巨大的目录,为了防止文件相互冲突,您可以为它们提供带有前缀和后缀的详细名称。集成的 InnoDB / memcached 服务器允许您使用这些相同的键命名约定,并添加一个。@@table_id.key.table_id格式的键名被解码以引用特定的 a 表,使用来自innodb_memcache.containers表的映射数据。在指定的表中查找或写入键。

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

得到@@table_x

后续的get、set、incr、delete等操作使用innodb_memcache.containers.name列中table_x指定的表。

于 2013-07-08T09:34:00.063 回答
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

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

于 2013-10-16T19:51:09.347 回答
-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 实例的连接就会保持打开状态。在正在运行的实例中从列表中添加或删除服务器时(例如,当启动另一个提到其他服务器的脚本时),连接是共享的,但脚本仅在脚本中明确配置的实例中进行选择。

于 2013-07-07T10:41:17.600 回答