Redis单机版+集群版搭建+简单使用

一、Redis的安装
1、安装gcc:
Redis是c语言开发的,需要gcc编译环境。查看是否已经安装gcc的命令:gcc
这里写图片描述
如果出现这样的情况,则说明系统没有安装gcc。
在线安装gcc命令:yum install gcc-c++
安装完毕效果图这里写图片描述
2、安装redis
redis安装包百度云链接:(redis-3.0.0.tar.gz)
链接:https://pan.baidu.com/s/1wA-SCLzJkKUYQZtbaxYtiA 密码:vmnf
安装步骤:
第一步:上传。redis的源码包上传到linux系统。redis-3.0.0.tar.gz
第二步:解压。解压缩redis。tar zxvf…
第三步:编译。进入redis源码目录。make
第四步:安装。make install PREFIX=/usr/local/java/redis
PREFIX参数指定redis的安装目录。一般软件安装到/usr目录下
这里写图片描述


二、redis的启动
1、前端启动:
在redis的安装目录下直接启动redis-server
[root@localhost bin]# ./redis-server
这里写图片描述
Ctrl+c关闭
注意:这种方式启动时,命令行不能退出,退出则关闭redis。一般不建议这种方式启动。
1、后台启动
第一步:把/usr/local/java/redis/redis-3.0.0/redis.conf复制到/usr/local/java/redis/bin目录下
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/java/redis/bin/
第二步:修改配置文件:vim redis.conf
这里写图片描述
第三步:启动redis
[root@localhost bin]# ./redis-server redis.conf
备注:查看redis进程:
[root@localhost bin]# ps aux|grep redis
三、连接redis
1、默认连接
[root@localhost bin]# ./redis-cli
默认连接localhost运行在6379端口的redis服务。
2、带IP地址和端口号连接
[root@localhost bin]# ./redis-cli -h 192.168.25.153 -p 6379
-h:连接的服务器的地址
-p:服务的端口号
3、关闭redis:[root@localhost bin]# ./redis-cli shutdown
四、Redis五种数据类型
1、String:key-value(做缓存)
Redis中所有的数据都是字符串。命令不区分大小写,key是区分大小写的。Redis是单线程的。Redis中不适合保存内容大的数据。
get、set、
incr:加一(生成id)
Decr:减一
2、Hash:key-fields-values(做缓存)
相当于一个key对于一个map,map中还有key-value
使用hash对key进行归类。
Hset:向hash中添加内容
Hget:从hash中取内容
3、List:有顺序可重复
4、Set:元素无顺序,不能重复
5、SortedSet(zset):有顺序,不能重复
Key命令
设置key的过期时间。
expire key second:设置key的过期时间
ttl key:查看key的有效期
persist key:清除key的过期时间。Key持久化
五、Redis的持久化方案
Redis的所有数据都是保存到内存中的。
1、rdb形式:快照形式,定期把内存中当前时刻的数据保存到磁盘。Redis默认支持的持久化方案。
**2、aof形式:**append only file。把所有对redis数据库操作的命令,增删改操作的命令。保存到文件中。数据库恢复时把所有的命令执行一遍即可。
在redis.conf配置文件中配置。
rdb配置:
这里写图片描述
aof的配置:
这里写图片描述
两种持久化方案同时开启使用aof文件来恢复数据库。
六、Redis集群的搭建
6.1、redis-cluster架构图
这里写图片描述
架构细节:
(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.
(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
(4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value
Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点
6.2、Redis集群的搭建
Redis集群中至少应该有三个节点。要保证集群的高可用,需要每个节点有一个备份机。
Redis集群至少需要6台服务器。
搭建伪分布式。可以使用一台虚拟机运行6个redis实例。需要修改redis的端口号7001-7006
这里写图片描述这里写图片描述
6.2.1集群搭建环境
1、使用ruby脚本搭建集群。需要ruby的运行环境。
安装ruby
yum install ruby
yum install rubygems
离线安装
这里写图片描述
2、安装ruby脚本运行使用的包。
[root@localhost ~]# gem install redis-3.0.0.gem
Successfully installed redis-3.0.0
1 gem installed
Installing ri documentation for redis-3.0.0…
Installing RDoc documentation for redis-3.0.0…
[root@localhost ~]#
这里写图片描述
[root@localhost ~]# cd redis-3.0.0/src
[root@localhost src]# ll *.rb
-rwxrwxr-x. 1 root root 48141 Apr 1 2015 redis-trib.rb
这里写图片描述
6.2.2搭建步骤
需要6台redis服务器。搭建伪分布式。
需要6个redis实例。
需要运行在不同的端口7001-7006
第一步:创建6个redis实例,每个实例运行在不同的端口。需要修改redis.conf配置文件。配置文件中还需要把cluster-enabled yes前的注释去掉。
这里写图片描述
第二步:启动每个redis实例
第三步:使用ruby脚本搭建集群。
./redis-trib.rb create –replicas 1 192.168.25.24:7001 192.168.25.24:7002 192.168.25.24:7003 192.168.25.24:7004 192.168.25.24:7005 192.168.25.24:7006
这里写图片描述
创建关闭集群的脚本:
[root@localhost redis-cluster]# vim shutdow-all.sh
redis01/redis-cli -p 7001 shutdown
redis01/redis-cli -p 7002 shutdown
redis01/redis-cli -p 7003 shutdown
redis01/redis-cli -p 7004 shutdown
redis01/redis-cli -p 7005 shutdown
redis01/redis-cli -p 7006 shutdown
[root@localhost redis-cluster]# chmod u+x shutdow-all.sh
6.2.3集群的使用方法
Redis-cli连接集群。
[root@localhost redis-cluster]# redis01/redis-cli -p 7002 -c
-c:代表连接的是redis集群
七、Jedis
添加jedis依赖

<!-- Redis客户端 -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.7.2</version>
    </dependency>

连接单机版

//测试单机版redis
    @Test
    public void testJedis() throws Exception {
        // 第一步:创建一个Jedis对象。需要指定服务端的ip及端口。
        Jedis jedis = new Jedis("192.168.206.128", 6379);
        // 第二步:使用Jedis对象操作数据库,每个redis命令对应一个方法。
        jedis.set("hello", "hello redis");
        String result = jedis.get("hello");
        // 第三步:打印结果。
        System.out.println(result);
        // 第四步:关闭Jedis
        jedis.close();
    }

连接单机版使用连接池

//连接单机版使用连接池
    @Test
    public void testJedisPool() throws Exception {
        // 第一步:创建一个JedisPool对象。需要指定服务端的ip及端口。
        JedisPool jedisPool = new JedisPool("192.168.206.128", 6379);
        // 第二步:从JedisPool中获得Jedis对象。
        Jedis jedis = jedisPool.getResource();
        // 第三步:使用Jedis操作redis服务器。
        jedis.set("jedis", "test");
        String result = jedis.get("jedis");
        System.out.println(result);
        // 第四步:操作完毕后关闭jedis对象,连接池回收资源。
        jedis.close();
        // 第五步:关闭JedisPool对象。
        jedisPool.close();
    }

使用集群版连接redis

//使用集群版连接redis
    @Test
    public void testJedisCluster() throws Exception {
        // 第一步:使用JedisCluster对象。需要一个Set<HostAndPort>参数。Redis节点的列表。
        Set<HostAndPort> nodes = new HashSet<>();
        nodes.add(new HostAndPort("192.168.206.128", 7001));
        nodes.add(new HostAndPort("192.168.206.128", 7002));
        nodes.add(new HostAndPort("192.168.206.128", 7003));
        nodes.add(new HostAndPort("192.168.206.128", 7004));
        nodes.add(new HostAndPort("192.168.206.128", 7005));
        nodes.add(new HostAndPort("192.168.206.128", 7006));
        JedisCluster jedisCluster = new JedisCluster(nodes);
        // 第二步:直接使用JedisCluster对象操作redis。在系统中单例存在。
        jedisCluster.set("hello", "100");
        String result = jedisCluster.get("hello");
        // 第三步:打印结果
        System.out.println(result);
        // 第四步:系统关闭前,关闭JedisCluster对象。
        jedisCluster.close();
    }

整合spring向业务中添加缓存

1、定义接口

public interface JedisClient {

String set(String key, String value);
String get(String key);
Boolean exists(String key);
Long expire(String key, int seconds);
Long ttl(String key);
Long incr(String key);
Long hset(String key, String field, String value);
String hget(String key, String field);
Long hdel(String key, String... field);

}

2、定义单机版实现类

public class JedisClientPool implements JedisClient {

@Autowired
private JedisPool jedisPool;

@Override
public String set(String key, String value) {
    Jedis jedis = jedisPool.getResource();
    String result = jedis.set(key, value);
    jedis.close();
    return result;
}

@Override
public String get(String key) {
    Jedis jedis = jedisPool.getResource();
    String result = jedis.get(key);
    jedis.close();
    return result;
}

@Override
public Boolean exists(String key) {
    Jedis jedis = jedisPool.getResource();
    Boolean result = jedis.exists(key);
    jedis.close();
    return result;
}

@Override
public Long expire(String key, int seconds) {
    Jedis jedis = jedisPool.getResource();
    Long result = jedis.expire(key, seconds);
    jedis.close();
    return result;
}

@Override
public Long ttl(String key) {
    Jedis jedis = jedisPool.getResource();
    Long result = jedis.ttl(key);
    jedis.close();
    return result;
}

@Override
public Long incr(String key) {
    Jedis jedis = jedisPool.getResource();
    Long result = jedis.incr(key);
    jedis.close();
    return result;
}

@Override
public Long hset(String key, String field, String value) {
    Jedis jedis = jedisPool.getResource();
    Long result = jedis.hset(key, field, value);
    jedis.close();
    return result;
}

@Override
public String hget(String key, String field) {
    Jedis jedis = jedisPool.getResource();
    String result = jedis.hget(key, field);
    jedis.close();
    return result;
}

@Override
public Long hdel(String key, String... field) {
    Jedis jedis = jedisPool.getResource();
    Long result = jedis.hdel(key, field);
    jedis.close();
    return result;
}

}

3、定义集群版实现类

public class JedisClientCluster implements JedisClient {

@Autowired
private JedisCluster jedisCluster;

@Override
public String set(String key, String value) {
    return jedisCluster.set(key, value);
}

@Override
public String get(String key) {
    return jedisCluster.get(key);
}

@Override
public Boolean exists(String key) {
    return jedisCluster.exists(key);
}

@Override
public Long expire(String key, int seconds) {
    return jedisCluster.expire(key, seconds);
}

@Override
public Long ttl(String key) {
    return jedisCluster.ttl(key);
}

@Override
public Long incr(String key) {
    return jedisCluster.incr(key);
}

@Override
public Long hset(String key, String field, String value) {
    return jedisCluster.hset(key, field, value);
}

@Override
public String hget(String key, String field) {
    return jedisCluster.hget(key, field);
}

@Override
public Long hdel(String key, String... field) {
    return jedisCluster.hdel(key, field);
}

}

4、配置:applicationContext-redis.xml

<!-- 配置单机版的连接 -->
<!-- <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
    <constructor-arg name="host" value="192.168.25.24"></constructor-arg>
    <constructor-arg name="host" value="192.168.206.128"></constructor-arg>
    <constructor-arg name="port" value="6379"></constructor-arg>
</bean>
<bean id="jedisClientPool" class="com.taotao.content.jedis.JedisClientPool"/> -->

<!-- 集群版的配置 -->
<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
    <constructor-arg name="nodes">
        <set>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="192.168.206.128"></constructor-arg>
                <constructor-arg name="port" value="7001"></constructor-arg>
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="192.168.206.128"></constructor-arg>
                <constructor-arg name="port" value="7002"></constructor-arg>
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="192.168.206.128"></constructor-arg>
                <constructor-arg name="port" value="7003"></constructor-arg>
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="192.168.206.128"></constructor-arg>
                <constructor-arg name="port" value="7004"></constructor-arg>
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="192.168.206.128"></constructor-arg>
                <constructor-arg name="port" value="7005"></constructor-arg>
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="192.168.206.128"></constructor-arg>
                <constructor-arg name="port" value="7006"></constructor-arg>
            </bean>
        </set>
    </constructor-arg>
</bean>
<bean id="jedisClientCluster" class="com.taotao.content.jedis.JedisClientCluster"/>

5、测试代码
//测试面向接口编程
    @Test
    public void testJedisClient() throws Exception {
        //初始化Spring容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-redis.xml");
        //从容器中获得JedisClient对象
        JedisClient jedisClient = applicationContext.getBean(JedisClient.class);
        jedisClient.set("first", "100");
        String result = jedisClient.get("first");
        System.out.println(result);
    }

6、向业务中添加缓存

//内容列表,展示前台首页广告
    public List<TbContent> getContentList(long cid) {
        //先查询缓存中是否有数据
        try {
            String json = jedisClient.hget(CONTENT_KEY, cid+"");
            if (StringUtils.isNotBlank(json)) {
                List<TbContent> jsonToList = JsonUtils.jsonToList(json, TbContent.class);
                return jsonToList;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        TbContentExample example = new TbContentExample();
        Criteria criteria = example.createCriteria();
        criteria.andCategoryIdEqualTo(cid);
        List<TbContent> list = contentMapper.selectByExample(example);

        //向缓存中保存数据
        try {
            jedisClient.hset(CONTENT_KEY, cid+"", JsonUtils.objectToJson(list));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return list;
    }

7、缓存同步
对内容信息做增删改操作后只需要把对应缓存删除即可
8、JsonUtils工具类

<!-- jackson工具包 -->
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.5</version>
    </dependency>
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonUtils {

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 将对象转换成json字符串。
     * <p>
     * Title: pojoToJson
     * </p>
     * <p>
     * Description:
     * </p>
     * 
     * @param data
     * @return
     */
    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将json结果集转化为对象
     * 
     * @param jsonData
     *            json数据
     * @param clazz
     *            对象中的object类型
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将json数据转换成pojo对象list
     * <p>
     * Title: jsonToList
     * </p>
     * <p>
     * Description:
     * </p>
     * 
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = MAPPER.readValue(jsonData, javaType);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}

猜你喜欢

转载自blog.csdn.net/wgq3773/article/details/80399720
今日推荐