LoginSignup
1
2

More than 5 years have passed since last update.

MySQLにmemcachedプラグインをインストールしてJavaからアクセスする

Last updated at Posted at 2018-02-08

MySQLにmemcachedプラグインを入れる

1.libevent-develをインストール
/bin/bash
# yum -y install libevent-devel
2. my.cnfにmemcacheの設定を追加
/etc/my.cnf
daemon_memcached_option = "-p11211"
daemon_memcached_engine_lib_name = innodb_engine.so
daemon_memcached_r_batch_size = 1
daemon_memcached_w_batch_size = 1
3.memcachedプラグインをインストールする
mysql
mysql> INSTALL PLUGIN daemon_memcached soname "libmemcached.so";
mysql> show plugins;

daemon_memcached というプラグインが入ったことを確認

4.テスト用のテーブルを作成する
mysql
mysql> use test
mysql> create table user (id varchar(16), passwd varchar(256), primary key(id)) engine=InnoDB;
mysql> insert into user (id, passwd) values ('user01', '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8');

※insertしたpasswdカラムの値は"password"をsha256したもの

5.memcache経由でアクセスできるようにする
mysql
mysql> insert into innodb_memcache.containers (`name`,`db_schema`,`db_table`,`key_columns`,`value_columns`,`flags`,`cas_column`,`expire_time_column`,`unique_idx_name_on_key`) VALUES ('user', 'test', 'user', 'id', 'passwd',0,0,0,'PRIMARY');
mysql> UNINSTALL PLUGIN daemon_memcached;INSTALL PLUGIN daemon_memcached soname "libmemcached.so";

@@(innodb_memcache.containersのnameカラムの値).keyとしてアクセス可能
$ telnet 127.0.0.1 11211 して get @@user.user01 とタイプした時にsha256の文字列が返ってくればOK

6.Java側を実装する

↓あたりからspymemcachedをダウンロードするhttp://www.java2s.com/Code/Jar/s/Downloadspymemcached27jar.htm
※もちろんMavenで対応してもOK

今回はID,PassをJSONでPOSTした際に、ユーザ登録があった場合には200、無かった(ID,Passが一致しない)場合には401が返ってくるRestAPIをJavaEEのJAX-RSで作成してみた。

Memcache.java
package memcached;

import java.net.InetSocketAddress;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

import javax.enterprise.context.RequestScoped;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

import net.spy.memcached.MemcachedClient;

@RequestScoped
@Path("/auth")
@Produces("application/json")
@Consumes("application/json")
public class Memcache {

    @POST
    public Response auth (Map<String, String> param) {
        ResponseBuilder response = null;
        try {
            MemcachedClient memcachedClient = new MemcachedClient (new InetSocketAddress("192.168.56.102", 11211));
            if ( sha256( param.get("password") ).equals( memcachedClient.get( "@@user." + param.get("id") ).toString() ) ) {
                response = Response.status(200);
            } else {
                response = Response.status(401);
            }
        } catch (Exception e) {
            response = Response.status(400);
        }
        return response.build();
    }

    private String sha256(String plaintext) throws Exception{
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        StringBuilder sb = new StringBuilder();
        md.update(plaintext.getBytes());
        for (byte b : md.digest()) {
            String hex = String.format("%02x", b);
            sb.append(hex);
        }
        return sb.toString();
    }
}

「value_columns: CHAR、VARCHAR、または BLOB カラムにマップされる必要があります」とのことで、JSON型のフィールドをそのままmemcachedで扱うことは不可能:cry:(telnetしてみると応答はあるけど中身ぐちゃぐちゃ)
https://dev.mysql.com/doc/refman/5.6/ja/innodb-memcached-internals.html
CASTすれば大丈夫なのか不明だが、何もせずとも対応できるようにしてくださいな。>Oracleさん

(追記)
generated columnを使って、JSON型のカラムからTEXT型のカラムを生成してvalue_columnsに指定してみた。

mysql
mysql> create table userinfo (id varchar(16), infojson json, userinfo text as (cast(infojson as char) engine=InnoDB;
mysql> insert into innodb_memcache.containers (`name`,`db_schema`,`db_table`,`key_columns`,`value_columns`,`flags`,`cas_column`,`expire_time_column`,`unique_idx_name_on_key`) VALUES ('userinfo', 'test', 'userinfo', 'id', 'userinfo',0,0,0,'PRIMARY');
mysql> UNINSTALL PLUGIN daemon_memcached;INSTALL PLUGIN daemon_memcached soname "libmemcached.so";

結果、NG!
逆(text型からjson型をgenerated column)なら出来るんだろうけど、json関数使った更新系クエリ使えないから美味しさ半減。。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2