redis笔记

前言

作为这个时代码代码的秃头人员,对 Redis 肯定是不陌生的,如果连 Redis 都没用过,还真不好意思出去面试,指不定被面试官吊打多少次。

毕竟现在互联网公司和一些创业公司都要用到 Redis,像亚马逊、谷歌、阿里、腾讯都要使用,可见精通 Redis 使用真的很有必要。

Redis介绍

Redis是一个key-value存储系统,它支持的value类型相对较多,包括string、list、set和zset,这些数据都支持push/pop/add/remove及交并补等操作,而且这些操作都是原子性的,在此基础上,redis支持各种不同方式的排序。为了保证效率,数据是缓存在内存中的,Redis会周期性的把数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave同步

Redis支持丰富的数据类型,最为常用的数据类型主要有五种:String、Hash、List、Set和Sort Set,Redis通常将数据存储到内存中,或被配置为使用虚拟内存,Redis有一个很重要的特点就是它可以实现持久化数据,通过两种方式可以实现数据持久化,一是RDB快照方式,将内存中的数据不断写入磁盘, 二是使用类似MySql的AOF日志方式,记录每次更新的日志,前者性能较高,但是可能会引起一定程度的数据丢失,后者相反,Redis支持即将数据到多台子数据库上,这种特性提高读取数据性能非常有益

Redis Cluster是一个实现了分布式且允许单点故障的Redis高级版本,它没有中心节点,各个节点地位一致,具有线性可伸缩的功能。Redis Cluster的分布式存储结构,其中节点与节点之间通过二进制协议进行通讯,节点与客户端之间通过ascii协议进行通信,在数据的放置策略上,Redis Cluster将整个key的数值域分成16384个哈希槽。每个节点上可以存储一个或多个哈希槽,也就是说当前Redis Cluster支持的最大节点就是16384

Redis 优势

  • 性能极高 – Redis 能读的速度是 110000 次/s,写的速度是 81000 次/s 。
  • 丰富的数据类型 – Redis 支持二进制案例的 Strings, Lists, Hashes, Sets 及Ordered Sets 数据类型操作。
  • 原子 – Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过
    MULTI 和 EXEC指令包起来。
  • 丰富的特性 – Redis 还支持 publish/subscribe, 通知, key 过期等等特性。

Redis使用场景

1.会话缓存(Session Cache)

最常用的一种使用 Redis 的情景是会话缓存(session cache)。用 Redis 缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗? 幸运的是,随着 Redis这些年的改进,很容易找到怎么恰当的使用 Redis 来缓存会话的文档。甚至广为人知的商业平台Magento 也提供 Redis 的插件。

2.全页缓存(FPC)

除基本的会话 token 之外,Redis 还提供很简便的 FPC 平台。回到一致性问题,即使重启了 Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似 PHP 本地 FPC。 再次以 Magento为例,Magento提供一个插件来使用 Redis 作为全页缓存后端。 此外,对 WordPress 的用户来说,Pantheon 有一个非常好的插件wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

3.队列

Reids 在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得 Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如 Python)对 list 的 push/pop 操作。 如果你快速的在 Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用 Redis 创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用 Redis 作为 broker,你可以从这里去查看。

4.排行榜/计数器

Redis 在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis 只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:
当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行: ZRANGE user_scores 0 10 WITHSCORES Agora Games 就是一个很好的例子,用 Ruby 实现的,它的排行榜就是使用 Redis 来存储数据的,你可以在这里看到。

5.发布/订阅

最后(但肯定不是最不重要的)是 Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用 Redis的发布/订阅功能来建立聊天系统!

Redis的使用与集群

1.创建一个springboot项目

导入pom依赖:

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

配置application.yml

spring:
  redis:
    cluster:
      #设置key的生存时间,当key过期时,它会被自动删除;
      expire-seconds: 120
      #设置命令的执行时间,如果超过这个时间,则报错;
      command-timeout: 5000
      #设置redis集群的节点信息,其中namenode为域名解析,通过解析域名来获取相应的地址;
      nodes: namenode22:6379,datanode23:6379,datanode24:6379,datanode25:6379,datanode26:6379,datanode27:6379

2.创建redis配置文件属性类

读取application.yml配置文件中的属性信息到bean中,并注入到spring容器;

//依赖注入
@Component
//该注解用于读取配置文件中的属性,其中prefix表示前缀;
@ConfigurationProperties(prefix = "spring.redis.cluster")
public class RedisProperties {
    private int expireSeconds;
    private String nodes;
    private int commandTimeout;

    public int getExpireSeconds() {
        return expireSeconds;
    }

    public void setExpireSeconds(int expireSeconds) {
        this.expireSeconds = expireSeconds;
    }

    public String getNodes() {
        return nodes;
    }

    public void setNodes(String nodes) {
        this.nodes = nodes;
    }

    public int getCommandTimeout() {
        return commandTimeout;
    }

    public void setCommandTimeout(int commandTimeout) {
        this.commandTimeout = commandTimeout;
    }

}

3.创建redis配置类

根据注入的RedisProperties对象来获取JedisCluster对象;

@Configuration
public class RedisConfig {

    @Autowired
    private RedisProperties redisProperties;

    @Bean
    public JedisCluster getJedisCluster(){
        //获取redis集群的ip及端口号等相关信息;
        String[] serverArray = redisProperties.getNodes().split(",");
        Set<HostAndPort> nodes = new HashSet<>();

        //遍历add到HostAndPort中;
        for (String ipPort : serverArray) {
            String[] ipPortPair = ipPort.split(":");
            nodes.add(new HostAndPort(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim())));
        }
        //构建对象并返回;
        return new JedisCluster(nodes, redisProperties.getCommandTimeout());
    }
}

4.创建redis集群接口

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);
}

实现对redis操作的主要的方法;

@Component
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);
    }
}

5.使用与测试

@RestController
public class RedisController {
    @Autowired
    private RedisProperties redisProperties;
    @Autowired
    private RedisConfig redisConfig;

    @Autowired
    private JedisClientCluster jedisClientCluster;

    @RequestMapping(value = "getRedisValue")
    public String getRedisValue(){
        System.out.println(redisProperties.toString());
        System.out.println(redisConfig.getJedisCluster().getClusterNodes());
        System.out.println(jedisClientCluster.get("yp"));
        jedisClientCluster.set("12","12");
        System.out.println(jedisClientCluster.get("12"));
        return jedisClientCluster.get("12");
    }
}

Redis的安装

下面介绍在Linux环境下,Redis的安装与部署

1.安装C++编译环境

在安装redis之前先安装C++编译环境,查看目前服务器上gcc的版本:gcc -v,

如果Linux系统没有安装gcc编译器,du会提示“Command not found”;如果提示命令找不到,则表明没有安装;

或者更新版本,不然后续make的时候会报错。 yum -y install gcc-c++

2.下载Redis

上官网下载Redis 压缩包,地址:https://redis.io/download

3、解压与编译。

解压命令 tar xzf redis-5.0.4.tar.gz

![](https://img-blog.csdnimg.cn/2020080615325999.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5Mzg3NDc1,size_16,color_FFFFFF,t_70)

进入到解压后的路径后,执行编译命令:

make

编译完成之后,可以看到解压文件夹redis下会有对应的src、conf等文件夹

进入到src目录,里边有很多关键性文件:

![](https://img-blog.csdnimg.cn/20200806154520234.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5Mzg3NDc1,size_16,color_FFFFFF,t_70)

5、启动redis

进入到redis的压缩目录的src下,开启服务

./redis-server

![](https://img-blog.csdnimg.cn/20190319233039439.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5Mzg3NDc1,size_16,color_FFFFFF,t_70)

启动成功后会显示redis的pid按住crtl+c 可以退出服务.

注意:这里直接执行Redis-server启动的Redis服务,是在前台直接运行的(效果如上图),也就是说,执行完该命令后,如果Lunix关闭当前会话,则Redis服务也随即关闭。正常情况下,启动Redis服务需要从后台启动,并且指定启动配置文件。所以执行下面的配置。

后台启动redis服务

a.修改/myredis/redis.conf配置文件,命令 vim redis.conf,将后台启动打开,即将daemonize选项由no置为yes

b.再次启动redis服务,并指定启动服务配置文件,执行命令

进入文件目录/usr/local/bin,执行./redis-server /myredis/redis.conf脚本文件:

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值