Xiaopei's DokuWiki

These are the good times in your life,
so put on a smile and it'll be alright

User Tools

Site Tools


it:key_value_memory_caching_memcached_redis

key value 内存缓存

做 cache 的话,memcached 比 redis 好太多!

更新 cache 的复杂方法是 CAS - 比较并交换:

  1. 设置 cache 的某个 key 的某个为为非法,此种 cache 不用也不被别的进程更新
  2. 更新 db
  3. 更新 cache

redis

效率

查看响应速度

$ redis-cli --latency -h 127.0.0.1 -p 6379
min: 0, max: 15, avg: 0.12 (2839 samples)

限制内存使用

Redis configuration – Redis

maxmemory 2mb
maxmemory-policy allkeys-lru # 避免 redis 已经被老数据撑满

del *

Starting with redis 2.6.0, you can run lua scripts, which execute atomically. I have never written one, but I think it would look something like this

> EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 *foo*

pub/sub

redis 除了 kv 存储外,还有一套 pub/sub 功能。

keys * 是看不到 pub/sub 的 channel 的。

需要 SUBSCRIBE first second 或者 PSUBSCRIBE news.*(p for pattern)订阅,才能拿到 pub 的消息。

命令和数据结构

基础操作

  • KEYS *
  • SET key value
  • GET key ⇒ value
  • SETNX key value
    • SET-if-not-exists
    • 成功返回 (integer) 0, 失败返回 (integer) 1, INCR 等方法的返回与此类似
  • DEL key
  • INCR key
    • redis 中有整数类型, INCR 可对整数 value + 1
    • 如果没有预先 SET 过 key, INCR key 等于 set key 1
    • INCR 是 原子操作 (atomic operation), 可避免以下情况
      1. Client A reads count as 10.
      2. Client B reads count as 10.
      3. Client A increments 10 and sets count to 11.
      4. Client B increments 10 and sets count to 11.
      
      We wanted the value to be 12, but instead it is 11!
  • EXPIRE key timeout
    • timeout 秒后 DEL key
  • TTL key
    • 设置 EXPIRE 后, 查看还有多少秒 key 过期

数据结构 - list

list, 是 “左 L 前, 右 R 后” 的字符串列表

  • RPUSH key value, 在队尾添加元素
  • LPUSH key value, 在队首添加元素
  • LLEN key, (LIST LEN) 队长度
  • LRANGE, 以闭区间 [] 获取 LIST 的一部分, 坐标从 0 开始, -1 为最后一个
    • LRANGE friends 0 -1, 获取整队
    • LRANGE friends 0 1
    • LRANGE friends 1 2
  • LPOP, 队首取出元素
  • RPOP, 队尾取出元素
  • 无法直接取出第 n 个元素

数据结构 - set

无序, 元素唯一

  • SADD key value
  • SREM key value, remove
  • SISMEMBER key value, is member
  • SMEMBERS key
  • SUNION key1 key2, 返回合集, 不会影响 key1 或 key2

数据结构 - sorted set

each value has an associated score. This score is used to sort the elements in the set.

  • ZADD key score value
  • ZRANGE key 0 -1
  • ZRANK key value, 返回 value 在 key 中按 score 排序的位置 (0, 1, …)
  • ZRANGEBYSCORE score_start score_end, 返回 score 范围的 values

数据结构 - hash

hash are maps between string fields and string values, so they are the perfect data type to represent objects

  • HSET key field value
  • HGETALL key, 返回 field 和 value 间隔的 LIST
  • HMSET key f1 v1 f2 v2 …, 批量设置
  • HGET key field
  • HINCRBY key field step, 注意 step 是必填的
  • HDEL key field

深度学习

memcached

配置

  • MAXCONN :- is used to set the maximum connections allowed to access memcached. It seems that each request will end up in one connection and if its full then the rest have to wait for its turn.
  • CACHESIZE :- This is what makes all the difference. In most cases the servers have huge chunks of RAM, mine had 15 GBs, it was an AMAZON xlarge instance. As we know memcached is all about RAM. And CACHESIZE defines the size of it. And to my surprise its in MBs. Means the default config was for just 64 MBs. Now that could be frustrating even for memcached when you are working on a site with a thousand nodes ;-) I tried Beefing it up to 4 GBs and also increased the MAXCONN to 2048 connections

example

  • 使用 memcached 前
     function get_foo(int userid) {
        data = db_select("SELECT * FROM users WHERE userid = ?", userid);
        return data;
     }
  • 使用 memcached 后
    •  function get_foo(int userid) {
          /* first try the cache */
          data = memcached_fetch("userrow:" + userid);
          if (!data) {
             /* not found : request database */
             data = db_select("SELECT * FROM users WHERE userid = ?", userid);
             /* then store in cache until next get */
             memcached_add("userrow:" + userid, data);
          }
          return data;
       }
    •  function update_foo(int userid, string dbUpdateString) {
         /* first update database */
          result = db_execute(dbUpdateString);
          if (result) {
             /* database update successful : fetch data to be stored in cache */
             data = db_select("SELECT * FROM users WHERE userid = ?", userid);
             /* the previous line could also look like data = createDataFromDBString(dbUpdateString); */
             /* then store in cache until next get */
             memcached_set("userrow:" + userid, data);
          }
       }
it/key_value_memory_caching_memcached_redis.txt · Last modified: 2017/12/25 21:52 by admin