【问题标题】:Using MYsql 5.6 Memcache使用 MYsql 5.6 内存缓存
【发布时间】:2013-07-03 03:25:24
【问题描述】:

我想我肯定遗漏了一些非常明显的东西,但我想做的是使用 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 查询,我将不胜感激!

【问题讨论】:

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

标签: php mysql memcached


【解决方案1】:

如果你还有默认表,你可以尝试使用 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】:

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

    如果映射中的表名是 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 具有相同的键值, 但存储在不同的表中,因此不会冲突。

    【讨论】:

    • 我知道这似乎是正确的,但我无法让它发挥作用。我不知道出了什么问题,按照所有步骤,仔细检查了你在这里写的内容,但它仍然一无所获
    【解决方案3】:

    发件人: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 请求,但不包含键部分。例如:

    获取@@table_x

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

    【讨论】:

      【解决方案4】:
      <?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 层来查询数据库,但我无法弄清楚如何指定我输入的键应该被查询的表。
      猜你喜欢
      • 2015-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      相关资源
      最近更新 更多