Redis-粗浅理解

什么是redis

典型的NoSql数据库服务器,在很多时候,人们只是将Redis视为Key/Value数据库服务器,然而事实并非如此,在目前的版本中,Redis除了Key/Value之外还支持List、Hash、Set和Ordered Set等数据结构,因此它的用途也更为宽泛。通常的用法就是将数据存放到内存到,由于内存存取速度快,官方称读取速度会达到30万次每秒,写速度在10万次每秒,所以redis被广泛应用在互联网项目中。

为什么使用redis

主要是性能和并发,以及在同类型产品中的优势。
A、对于性能来说,最好标准就是用户的良好体验,而用户的的良好体验最重要的就是请求是否可以迅速响应。这就要求数据库有良好的响应能力。当把需要不断请求且结果不频繁变动的sql,放到redis缓冲中,然后请求去缓冲中读取数据,就可以实现快速响应。
B、对于并发来说,在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问数据库。
C、和redis最相似的memcached,memcached只是单纯的key-value数据库,且没有提供任何数据持久化的功能,数据缓冲服务一旦宕机,服务器中的数据全部丢失。而redis在这两点上,都由于memcached,redis除了支持key-value外,还支持List、Hash、Set和Ordered Set等数据结构,而且redis还提供了两种持久化的方式:RDB和AOF。

使用例子

项目中的首页信息要存放在Redis中,因为访问频率高,允许有缓存的数据。;

redis单机版安装

第一步:安装gcc编译环境:yum install gcc-c++
第二步:把redis的源码上传到linux服务器。
第三步:解压缩。:tar -zxvf redis-3.0.0.tar.gz
第四步:make
第五步:make install PREFIX=/usr/local/
第六步:启动redis: ./redis-server redis.conf;启动前需要修改配置文件,将daemonize改为yes;
这里写图片描述

单机版测试

//使用连接池
    @Test
    public void testJedisPool() throws Exception {
        //创建一个连接池对象
        //系统中应该是单例的。
        JedisPool jedisPool = new JedisPool("192.168.128.111", 6379);
        //从连接池中获得一个连接
        Jedis jedis = jedisPool.getResource();
        jedis.set("test", "hello jedis");
        String result = jedis.get("test");
        System.out.println(result);
        //jedis必须关闭
        jedis.close();

        //系统关闭时关闭连接池
        jedisPool.close();

    }

如果测试的时候出现请求超时的错误:
这里写图片描述
只要关闭centos防火墙,便可搞定:systemctl stop firewalld.service

redis集群版部署

集群中应该至少有三个节点,每个节点有一备份节点。需要6台服务器。
搭建伪分布式,需要6个redis实例。
搭建集群的步骤:
第一步:创建6个redis实例指定端口从7001到7006
第二步:修改redis.conf 打开Cluster-enable yes前面的注释。
第三步:需要一个ruby脚本。在redis源码文件夹下的src目录下。redis-trib.rb
第四步:把redis-trib.rb文件复制到到redis-cluster目录下。
第五步:执行ruby脚本之前,需要安装ruby环境。
1、yum install ruby
2、yum install rubygems
3、安装redis-trib.rb运行依赖的ruby的包: gem install redis-3.0.0.gem
第六步:用脚本启动所有的redis实例。
这里写图片描述
第七步:使用redis-trib.rb创建集群,执行以下命令

./redis-trib.rb create --replicas 1 192.168.128.111:7001 192.168.128.111:7002 192.168.128.111:7003
 192.168.128.111:7004 192.168.128.111:7005  192.168.128.111:7006

这里写图片描述

集群版测试

//连接redis集群
    @Test
    public void testJedisCluster() throws Exception {
        //创建一个JedisCluster对象
        Set<HostAndPort> nodes = new HashSet<>();
        nodes.add(new HostAndPort("192.168.128.111", 7001));
        nodes.add(new HostAndPort("192.168.128.111", 7002));
        nodes.add(new HostAndPort("192.168.128.111", 7003));
        nodes.add(new HostAndPort("192.168.128.111", 7004));
        nodes.add(new HostAndPort("192.168.128.111", 7005));
        nodes.add(new HostAndPort("192.168.128.111", 7006));
        //在nodes中指定每个节点的地址
        //jedisCluster在系统中是单例的。
        JedisCluster jedisCluster = new JedisCluster(nodes);
        jedisCluster.set("name", "zhangsan");
        jedisCluster.set("value", "100");
        String name = jedisCluster.get("name");
        String value = jedisCluster.get("value");
        System.out.println(name);
        System.out.println(value);


        //系统关闭时关闭jedisCluster
        jedisCluster.close();
    }

项目中使用jedis

单机版实现类

/**
 * redis客户端单机版实现类
 * <p>Title: JedisClientSingle</p>
 * @author  吕德彪
 * @date    2018年8月24日 10:49:53 * @version 1.0
 */
public class JedisClientSingle 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;
    }

    //HSet:将哈希表key中域field设置成指定的value
    @Override
    public Long hset(String key, String item, String value) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.hset(key, item, value);
        jedis.close();
        return result;
    }

    //HGet:返回哈希表key中给定field的值
    @Override
    public String hget(String key, String item) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.hget(key, item);
        jedis.close();
        return result;
    }

    //incr递增1并返回递增后的结果;
    @Override
    public Long incr(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.incr(key);
        jedis.close();
        return result;
    }

    //decr递减1并返回递减后的结果;
    @Override
    public Long decr(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.decr(key);
        jedis.close();
        return result;
    }

    //为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。
    @Override
    public Long expire(String key, int second) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.expire(key, second);
        jedis.close();
        return result;
    }

    //以秒为单位,返回给定 key 的剩余生存时间
    @Override
    public Long ttl(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.ttl(key);
        jedis.close();
        return result;
    }

}

集群版实现类

/**
 * redis客户端集群版实现类
 * <p>Title: JedisClientCluster</p>
 * @author  吕德彪
 * @date    2018年8月24日 10:51:09
 * @version 1.0
 */
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 Long hset(String key, String item, String value) {
        return jedisCluster.hset(key, item, value);
    }

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

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

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

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

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

}

Spring的配置
单机版和集群版配置不能同时存在,使用单机版时需要把集群版注释掉,使用集群版需要把单机版注释掉。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

    <!-- 包扫描器,扫描带@Service注解的类 -->
    <context:component-scan base-package="com.taotao.rest.service"></context:component-scan>

    <!-- 配置redis客户端单机版 -->
    <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
        <constructor-arg name="host" value="192.168.128.111"></constructor-arg>
        <constructor-arg name="port" value="6379"></constructor-arg>
    </bean>
    <!-- 配置redis客户端实现类 -->
    <bean id="jedisClientSingle" class="com.taotao.rest.component.impl.JedisClientSingle"/>

    <!-- 配置redis客户端集群版 -->
    <!-- <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
        <constructor-arg>
            <set>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.128.111"/>
                    <constructor-arg name="port" value="7001"/>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.128.111"/>
                    <constructor-arg name="port" value="7002"/>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.128.111"/>
                    <constructor-arg name="port" value="7003"/>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.128.111"/>
                    <constructor-arg name="port" value="7004"/>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.128.111"/>
                    <constructor-arg name="port" value="7005"/>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.128.111"/>
                    <constructor-arg name="port" value="7006"/>
                </bean>
            </set>
        </constructor-arg>
    </bean>
    <bean id="jedisClientCluster" class="com.taotao.rest.component.impl.JedisClientCluster"/> -->
</beans>

测试

@Test
    public void testJedisClientSpring() throws Exception {
        //创建一个spring容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-*.xml");
        //从容器中获得JedisClient对象
        JedisClient jedisClient = applicationContext.getBean(JedisClient.class);
        //jedisClient操作redis
        jedisClient.set("cliet1", "1000");
        String string = jedisClient.get("cliet1");
        System.out.println(string);
    }

结语

在项目中使用的时候,可以将单机版实现类和集群版实现类以及读取配置文件都封装在工具类中,然后调用工具类,使用相应的方法即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子松的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值