使用Redis做缓存——个人笔记

1、linux 下 Redis安装
1)在redis官网下载tar.gz压缩包,写这篇文章的时候最新版本为redis-3.2.9。
2)在Terminal找到对应文件,使用解压命令

tar -xzvf redis-3.2.9.tar.gz

3) cd进入解压后的redis文件夹,使用“make”命令安装。在安装之前,保证linux已经配置好GCC环境。
4) 安装完成后,找到目录中的可执行文件。启动redis服务。可以将自己的配置信息写到redis.conf。例如redis的持久化RDB、AOF的配置等。

redis-server   redis.conf

2、Java 项目引入 Jedis 客户端
1)现在一般都用maven进行项目的管理。首先在pom.xml文件中,添加Jedis客户端的依赖。

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.7.3</version>
        </dependency>

因为redis是使用“key-value”方式将数据存储的,而且value通常是字符串对象,而不是自定义对象。为了存储我们声明的对象,必须将其序列化为二进制数组字符串,然后再存储到redis服务器中。使用性能最好的ProtoStuff 将对象序列化。

    <dependency>
        <groupId>com.dyuproject.protostuff</groupId>
        <artifactId>protostuff-core</artifactId>
        <version>1.0.8</version>
    </dependency>
    <dependency>
        <groupId>com.dyuproject.protostuff</groupId>
        <artifactId>protostuff-runtime</artifactId>
        <version>1.0.8</version>
    </dependency>

2)Redis操作也是DAO层的操作,我们需要写一个RedisDao。采用jedis连接池的方式来操作redis。

    private final JedisPool jedisPool;
    //声明一个构造函数,用于spring构造函数注入
    public RedisDao(String ip, int port) {
        jedisPool = new JedisPool(ip, port);
    }

因为我将DAO组件都托管到了spring容器中,所以要spring配置文件要写上对应的RedisDaoBean,而且采用的是构造函数注入方式。

    <bean id="redisDao" class="org.seckill.dao.cache.RedisDao">
        <constructor-arg index="0" value="localhost"/>
        <constructor-arg index="1" value="6379"/>
    </bean>

之后就可以进行读写操作。
3、Java使用Redis存储、读取对象实例

    private RuntimeSchema<Seckill> schema = RuntimeSchema.createFrom(Seckill.class);

    public Seckill getSeckill(long seckillId) {
        // redis操作逻辑
        try {
            Jedis jedis = jedisPool.getResource();
            try {
                String key = "seckill:" + seckillId;
                // 并没有实现内部序列化操作
                // get-> byte[] -> 反序列化 ->Object(Seckill)
                // 采用自定义序列化
                // protostuff : 要求是pojo对象.
                byte[] bytes = jedis.get(key.getBytes());
                // 缓存中获取到bytes
                if (bytes != null) {
                    // 空对象
                    Seckill seckill = schema.newMessage();
                    ProtostuffIOUtil.mergeFrom(bytes, seckill, schema);
                    // seckill 被反序列化
                    return seckill;
                }
            } finally {
                jedis.close();
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

    public String putSeckill(Seckill seckill) {
        // set Object(Seckill) -> 序列化 -> byte[]
        try {
            Jedis jedis = jedisPool.getResource();
            try {
                String key = "seckill:" + seckill.getSeckillId();
                byte[] bytes = ProtostuffIOUtil.toByteArray(seckill, schema,
                        LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
                // 超时缓存
                int timeout = 60 * 60;// 1小时
                String result = jedis.setex(key.getBytes(), timeout, bytes);
                return result;
            } finally {
                jedis.close();
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        return null;
    }

4、Juni4测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:spring/spring-dao.xml" })
public class RedisDaoTest {
    private long id = 1001;
    @Autowired
    private RedisDao redisDao;

    @Autowired
    private SeckillDao seckillDao;

    @Test
    public void testSeckill() throws Exception {
        // get & put
        Seckill seckill = redisDao.getSeckill(id);
        if (seckill == null) {
            seckill = seckillDao.queryById(id);
            if (seckill != null) {
                String result = redisDao.putSeckill(seckill);
                System.out.println("RedisDao的返回结果:" + result);
                seckill = redisDao.getSeckill(id);
                System.out.println("从Redis中取出seckill:" + seckill);
            }
        }
    }

}

5、其他
在跟着mooc教程做的练习项目中,第一次接触到redis作为缓存使用。项目的完整源码地址 https://github.com/kaka0509/seckill
以前实习听研究所的工程师提过,在真实项目中,通常会做成缓存服务器集群来应对高并发。不直接去和数据库进行数据交换。借助消息队列暂存对数据的一些操作,最后再从队列中逐渐推到MYSQL数据库。很可惜没有遇上实践的机会,只能以后再深入学习了。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值