Redis 学习笔记

一、为什么要选择redis
   1)性能好:采用缓存性能会比数据库好很多。
   2)可扩展:采用缓存可以很容易扩展,能够通过增加节点来扩展容量和性能,这在解决大流量,高并发的网站性能时是非常关键的。
   3)丰富的存储结构:如果只有以上两点,那么跟memcached也没什么区别,相比memcached,redis可以存储MAP,SET,LIST等集合类型,在处理复杂数据时,能够提升性能。
   4)可持久化:redis提供了两种持久化机制 AOP和RDB。
   5)主备:支持1个master n个slave的模式,同步性能非常好。
   6)集群:在redis3.x版本中,已经全面支持集群功能。当master失效之后,Sentinel会自动从slave中选举一个成为master。
   7)客户端工具支持:有良好的客户端工具,可以实时查看缓存中的数据,检测缓存的运行情况。
二、redis安装篇
   1)windows版
      下载地址: https://github.com/MSOpenTech/redis/releases/download/win-2.8.2104/Redis-x64-2.8.2104.zip
      下载解压就可以了。
      服务端启动命令: redis-server.exe redis.windows.conf
     客户端链接命令: redis-cli.exe -h localhost -p 6379
   2)linux版
      下载地址: http://download.redis.io/releases/redis-3.0.4.tar.gz
     (1)下载后解压 tar -xzf redis-3.0.4.tar.gz
     (2)然后切换到解压目录(redis-3.0.4),输入命令:makefile
     (3)新建一个目录bin作为运行目录,在编译完之后,将当前目录的redis.conf和子目录src中的redis-server, redis-cli拷贝到bin中。
      (4)修改权限,chmod 777 redis*
     (5)服务端启动命令:./redis-server ./redis.conf
        客户端链接命令:./redis-cli -h localhost -p 6379
        当然也可以使用windows的客户端连接。
三、redis开发篇
   1)客户端采用jedis是个不错的选择。最新版2.7.2兼容redis 2.x 和 3.x。
       jedis下载地址:https://codeload.github.com/xetorthio/jedis/zip/jedis-2.7.2
   2) redis的命令基本上分几大类: 字符串处理类,MAP处理类,SET处理类,LIST处理类等。命令参考文档: http://redisdoc.com/。
      这些命令既可以在客户端中运行,也对应jedis的API方法,对,就这么好用。
      说这么多,给点示例吧.

  
package cn.gov.zjport.learning.redis.redis;

import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author: zhenggm
 */
public class RedisDemo {
	private static final int DEFAULT_PORT=6379;
	private static final int DEFAULT_TIMEOUT=2000;
	
    JedisPool pool;
    Jedis jedis;
    @Before
    public void setUp() {
        pool = new JedisPool(new JedisPoolConfig(), "localhost", DEFAULT_PORT, DEFAULT_TIMEOUT, "zjport");//new JedisPool(new JedisPoolConfig(), "localhost");
        jedis = pool.getResource();
    }

    /**
     * Redis存储初级的字符串
     * CRUD
     */
    @Test
    public void testString(){
        //-----添加数据----------
    	//向key-->name中放入了value-->zhenggm
        jedis.set("name","zhenggm");
        //执行结果:zhenggm
        System.out.println(jedis.get("name"));

        //-----修改数据----------
        //将key-->name的value改为zhangsan
        jedis.set("name","zhangsan");
        //执行结果:zhangsan
        System.out.println(jedis.get("name"));
        
        //-----删除数据----------
        //删除key对应的记录
        jedis.del("name");
        //执行结果:null
        System.out.println(jedis.get("name"));

        /**
         * mset(multi set) 相当于
         * jedis.set("name","zhenggm");
         * jedis.set("company","zjport.gov.cn");
         */
        jedis.mset("name","zhenggm","company","zjport.gov.cn");
        
        /**
         * mget(multi get)
         * 执行结果: [zhenggm, zjport.gov.cn]
         */
        System.out.println(jedis.mget("name","company"));

    }

    /**
     * jedis操作Map
     */
    //@Test
    public void testMap(){
        Map<String,String> user=new HashMap<String,String>();
        user.put("name","zhenggm");
        user.put("company","zjport.gov.cn");
        //将map集合保存到缓存中
        jedis.hmset("user",user);
        //获取user的name字段
        System.out.println(jedis.hmget("user", "name"));
        //获取user的全部字段
        System.out.println(jedis.hgetAll("user"));
        
        //删除用户
        jedis.del("user");
    }

    /**
     * jedis操作List
     */
    //@Test
    public void testList(){
       //先向缓存中插入数据
       jedis.lpush("lname","zhangsan");
       jedis.lpush("lname","lisi");
       jedis.lpush("lname","wangwu");
       //再取出所有数据jedis.lrange是按范围取出,
       // 第一个是key,第二个是起始位置,第三个是结束位置,jedis.llen获取长度 -1表示取得所有
       System.out.println(jedis.lrange("lname",0,-1));
       
       //删除list
       jedis.del("lname");
    }

    /**
     * jedis操作Set
     */
    //@Test
    public void testSet(){
        jedis.sadd("sname","zhangsan");
        jedis.sadd("sname","lisi");
        jedis.sadd("sname","wangwu");
       
        System.out.println(jedis.smembers("sname"));//获取所有加入的value
        
        //删除某一个
        jedis.srem("sname", "lisi");
        //删除整个set
        jedis.del("sname");
        
        //批量添加
        jedis.sadd("sname", "zhangsan", "lisi","wangwu"); 
    }
   

    //@Test
    public void test() throws InterruptedException {
    	//返回当前库中所有的key
        System.out.println(jedis.keys("*")); 
        //返回当前db的key数量
        System.out.println(jedis.dbSize());
        //设置"sname" 10秒后过期,过期的数据会被自动删除
        jedis.expire("sname", 10);
        //清空当前数据库数据
        jedis.flushDB();
        //更改DB,1个redis server默认拥有16个DB,所有DB数据物理隔离
        jedis.select(1);
        //清空所有DB
        jedis.flushAll();
        
        jedis.select(0);
        jedis.sadd("sname", "zhangsan","lisi","wangwu");
        //将sname从db0转移至db1
        jedis.move("sname", 1);
        //返回当前db(db0)的key数量
        System.out.println(jedis.dbSize());
        //返回db1的key数量
        jedis.select(1);
        System.out.println(jedis.dbSize());
    } 
}

以上示例的连接池是最简单的,在实际使用中,JedisPoolConfig还有很多属性可以设置。
//控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted。
	private Integer maxTotal;
	//控制一个pool最多有多少个状态为idle(空闲)的jedis实例;
    private Integer maxIdle;
    //控制一个pool最少有多少个状态为idle(空闲)的jedis实例;
    private Integer minIdle;
    //表示当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
    private Integer maxWaitMillis;
    //在获取连接的时候检查有效性
    private Boolean testOnBorrow;
  


四、redis维护篇
   主要涉及redis.conf的设置
   1)设置redis server的访问密码为123456: requirepass 123456
   2)建议同时开启rdb和aop的持久化策略,rdb由于每次save都需要全量持久化,因此建议不要频繁持久化,导致性能问题。aop由于每次是增量写日志,因此可以比较频繁的写出,但是文件比较大,且相对容易坏,建议每秒写一次。
    3)默认是不开启aop持久化的,如果要开启,需要将appendonly 改为yes.
   4)maxmemory不要大于系统内存,且要比预估的业务最大容量大一些,因为redis有一部分空间是需要用作同步或者写入磁盘的预留。设置了maxmemory,当业务量超过阀值时,会将设置了过期时间的key,按照最近最少使用的策略删除,如果这些key也删除了,但仍超出,redis可能会崩溃(我用的windows版本出现过)。
   5)有一些重要的命令,如flushall, flushdb, 如果让人不小心执行了,那数据就丢失了,可以在配置文件中使用rename-command flushall "" ,将命令禁用。
   6)主从设置特别简单,主服务器的配置与没有主从配置是一模一样。从服务器的配置也就是使用 slaveof master的地址 master的端口 即可。由于redis的主从同步是另起线程进行的,因此不影响redis-master的服务性能。值得注意的是,由于redis的主从同步是非常快的,因此主服务器如果宕机或其他误操作导致内存丢失,一定要将从服务器的主从同步关闭。否则主服务器一启动,从服务器马上也会同步,导致内存丢失。关闭命令 slaveof no one
   7)如果master设置了密码, 那么还需要设置 masterauth password。
   8)如果主服务器宕机,可以不用停服务修改redis配置。使用客户端工具连上之后,使用config get命令可以看到配置文件中的每个配置项。使用config set命令设置其中的配置项。修改之后,记得使用config rewrite命令,将修改的内容同步到物理配置文件中,这样重启之后,配置也不会丢失。
   9)info命令可以看缓存的实时状态。
   10)monitor命令可以监控缓存的实时运行命令。
   11)如果要关闭server,不要直接kill或者在windows中关闭server窗口,这样会造成还未持久化的数据丢失。可以使用客户端连上之后,敲命令 shutdown.

你可能感兴趣的:(redis,入门,教程,实战)