Redis practice(一)基础篇

引言

先罗列一下缓存的基本概念。

所有类型的缓存:

  • L1 L2: CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多
  • DB cache(mysql query cache)
  • Brower
  • CDN
  • Mobile image cache

那些数据适合缓存:

  • 热点数据:top10,秒杀
  • 中间结果:比如哨兵的报警表达式触发次数,这次次数需要累计起来,存入数据库似乎没有意义
  • 预计算结果:计数、总量、max avg等统计结果。

常用的缓存框架

  • Ehcache: “JAVA’S MOST WIDELY-USED CACHE”,rmi协议支持jvm间数据同步问题
  • Spring cache :spring 给出的 缓存抽象,不是具体实现
    这些都属于本地缓存,Ehcache可以满足JVM间数据同步的问题。具体实现可以用spring cache + echcache

常用的缓存数据库

  • Map,虽然听起来有点土,但是属于程序猿做本地缓存的一种办法
  • Redis
  • MemCached

那么离不开这两者的比较:
Redis vs MemCached

item Redis MemCached
高可用 支持 自己实现
持久化 支持 不支持
数据类型 5种类型 String类型
线程 单线程 多线程
事务 支持 使用CAS命令支持

还有以下特点:

  • Both fast enough
  • Memcached is suitable for small and static data
  • Redis is preferable for structured data
  • Data can be persisted in Redis
  • If only one can be choosed, Redis is a better choice _

Redis属于缓存数据库

应用

  • 业务层缓存 (spring cache)
  • 持久层缓存 (Mybatis的二级缓存)
  • 数据层缓存 (eg:mysql query cache)

架构

  • 本地缓存 Map Ehcache
  • 分布式缓存 JBossCache
  • 集中式缓存 memcached redis

Redis安装及配置文件,及启动

安装的话就不用赘述了,从官方下一个tar包,比如http://download.redis.io/releases/redis-2.8.24.tar.gz
解压make,make install即可

Redis.conf
基本配置

  • pidfile 记录redis-server的pid文件路径
  • port Redis-server的监听端口
  • daemonize Redis-server配置成守护进程
  • loglevel Redis-server的日志级别(warning, notice,verbose,debug)
  • logfile 日志文件路径
  • requirepass 密码
  • maxmemory Redis能使用的最大内存量
  • maxmemory-policy 内存用完后的置换策略
    • volatile-lru:设置了过期时间的key中,删除最近最少用的key
    • allkeys-lru:所有的key中,删除最近最少用的key
    • noeviction:不置换,直接返回OOM错误
    • 其他。
  • databases 与mysql类似,一个redis实例中可以分多个库
    • 相同的库key是唯一的,不同的库key可以复用
    • 此配置项配置redis中库的个数

还有一些其他比如持久化和高可用的配置,另外一篇进阶篇会介绍。
更详细的文档,请参考官方:详细配置

服务器端启动:

redis-server redis.conf

客户端访问:

redis-cli -h host -p port -a auth

Redis常用数据类型

Tips: 命令大全试用网站

String类型

格式:"key" : "value"
常用命令:

  • set key value
  • get key
  • del key
  • incr/decr key
  • setex key seconds value
List

格式:类似于JAVA的List类型,"key":["value1","value2"]
常用命令:

  • lpush key value1 value2 …
  • lrange key start end
  • lrem count value
  • lindex key index
  • llen key
Hash

格式:类似于Java中的Map类型,"key":{"field1":"value1", "field2":value2,...}
常用命令:

  • hset key field value
  • hget key field
  • hdel key field1 field2…
  • hkeys key
  • hvals key
Set

格式:类似于Java中的set类型。"key":{"member1","member2",...}
常用命令:

  • sadd key member1 member2 …
  • srem key member1 member2 …
  • smembers
  • scard key
  • sinter key1 key2
  • sunion key1 key2
Sorted Set

格式: “key”: {("score1","memeber1", ("score2","memeber2")...)
常用命令:

  • zadd key score member
  • zrem key member
  • zrangebyscore key min max (withscores)
  • zcard key
其他常用命令
  • Keys + 匹配条件: keys * : 返回所有key
  • expire key seconds: 设置key的过期时间
  • ttl key: 查询key的过期时间
  • type key: 查询key的类型
  • exists key: 检查key是否存在
  • Publish/subcribe:
    • 发布一个推送频道以及订阅一个推送频道
    • 推送端和接收端均连上同一个redis
    • Subscribe + channel1 + channel2
    • Publish channel1 “hello world”
    • 类似于MQ
  • Multi/exec/discard
    • 事务
    • 要么全成功,要么全回滚

常用的客户端

Linux

Redis-cli:安装后自带

Windows

Redis destop manger

支持的编程语言

JAVA

Jedis

public class SharedJedisTest {
    public  static JedisPoolConfig poolConfig = new JedisPoolConfig();
    public  static List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
    static {
        poolConfig.setMaxTotal(100);
        poolConfig.setMaxIdle(10);
        poolConfig.setMaxWaitMillis(2000);
        JedisShardInfo info1 = new JedisShardInfo("10.165.124.10",16379);
        info1.setPassword("123456");
        JedisShardInfo info2 = new JedisShardInfo("10.165.124.10",16381);
        info2.setPassword("123456");
        shards.add(info1);
        shards.add(info2);
    }
    public static ShardedJedisPool shardedJedisPool = new ShardedJedisPool(poolConfig,shards);

    public static void main(String[] args){
        ShardedJedis jedis = null;
        try {
            jedis = shardedJedisPool.getResource();
            for (int i =0; i<50; i++){
                String key = String.format("key%d",i);
                String value = String.format("value%d",i);
                jedis.set(key, value);
                Client client1= jedis.getShard(key).getClient();
                System.out.println(String.format(("%s in server: %s, and port is: %d"),key,client1.getHost(),client1.getPort()));
            }
        }finally {
            if (jedis != null){
                jedis.close();
            }
        }

    }
}
Python

pip install redis

import redis


def addString():
    redis_cli.set('string', 'value1')
    print redis_cli.get('string')


def addList():
    redis_cli.lpush('list', 'value1')
    print redis_cli.lrange('list', 0, -1)


def addHash():
    redis_cli.hmset('hash', {'field1': 'value1', 'field2': 'value2', 'field3': 'value3'})
    print redis_cli.hmget('hash', 'field1', 'field3')
    print redis_cli.hkeys('hash')
    print redis_cli.hvals('hash')


def addSet():
    redis_cli.sadd('set', {'member1': 'value1', 'member2': 'value2', 'member3': 'value3'})
    redis_cli.sadd('set', 'member4', 'member5')
    print redis_cli.smembers('set')
    print redis_cli.scard('set')


def addSortedSet():
    redis_cli.zadd('SortedSet', memeber1=100, memeber2=80, memeber3=60, memeber4=30)
    print redis_cli.zcount('SortedSet', min=20, max=90)
    print redis_cli.zrangebyscore('SortedSet', min=0, max=90)


if __name__ == '__main__':
    redis_cli = redis.Redis(host='10.165.124.10', port=16379, db=0, password='123456')
    redis_cli_db1 = redis.Redis(host='10.165.124.10', port=16379, db=1, password='123456')

    # base opeartion for String List Set Hash SortedSet
    # addString()
    # addList()
    # addHash()
    # addSet()
    # addSortedSet()

    # use pipeline 大量写入
    for i in range(13000, 13050):
        string_key = 'stringkey' + str(i)
        list_key = 'listkey' + str(i)
        set_key = 'setkey' + str(i)
        hash_key = 'hashey' + str(i)
        z_key = 'zkey' + str(i)

        print "========= add keys starts ========"

        redis_cli_db1.set(string_key, 'string value1')
        print ("add string key %s, value %s", string_key, redis_cli_db1.get(string_key))

        redis_cli_db1.rpush(list_key, 'list value1','list value2', 'list value3')
        print ("add list key %s, value %s", list_key, redis_cli_db1.lrange(list_key, start=0, end=-1))

        redis_cli_db1.sadd(set_key, 'member1', 'member2', {'member1': 'value1', 'member3': 'value3'})
        print("add set key %s, value %s", set_key, redis_cli_db1.smembers(set_key))

        redis_cli_db1.hmset(hash_key, {'field1': 'value1', 'field2': 'value2', 'field3': 'value3'})
        print("add hash key %s, keys = %s values = %s", \
              hash_key, redis_cli_db1.hkeys(hash_key), redis_cli_db1.hvals(hash_key))

        redis_cli_db1.zadd(z_key, memeber1=100, memeber2=80, memeber3=60, memeber4=30)
        print("add sorted key %s, keys = %s values = %s", \
              z_key, redis_cli_db1.zremrangebyscore(z_key, min=0, max=90))

其他

  • Ruby:Redis-rb
  • PHP: phpredis
  • C++:hiredis.h

Reference

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容