Redis

概述

简介
NoSQL : Not only SQL,泛指一切非关系型数据库
关系型数据库:指以表的形式来保存数据库,以键/表的形式维护数据库之前的关系。如 Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL
非关系型数据库:泛指 关系型数据库之外其它类型的数据库 。如 NoSql、Cloudant等

关系型数据库的缺点

  • 高并发问题:海量的请求同时访问数据库
  • 高性能问题:数据量越来越大,需要从海量的数据量瞬间访问/操作某一些数据
  • 高扩展问题:数据库的集群,数据的迁移和移植

非关系型数据库的优点

  • 实现高性能要求:数据之间没有关系,所以数据的存取效率是非常高
  • 数据结构非常灵活:不以表的形式保存数据,可以以任何适合的格式来保存数据
  • 高扩展的优点:可以非常灵活进行数据移植

web 应用开发中非关系型数据库的使用

仍然是以关系型数据库来持久化报错数据,可以维护数据之间的业务关系。非关系型数据库作为补充。可以用来提升数据库的存取效率。
通常把 Redis 数据库与作为数据缓存,缓存了一些经常读取,但不经常修改的数据。列如:商品的分类信息,可以放在在缓存里。页面需要显示分类的时候,从缓存里读取,速度或比较快,可以有效提高 web 应用的访问性能。

Redis

C编写的免费开源,以 key-value 存取数据的非关系型数据库,把数据存储到内存中,而不是磁盘中,有非常高的读写性能。
Redis 的端口:6379 merz

操作Redis

Redis 的数据类型

以 key-value 保存数据
key:始终是字符串。通常来说,key的长度不要超过1024个字节,否则会影响数据的读写性能。
value:数据类型是五种 :

  • string:字符串类型,一个string可以保存512M数据
  • hash:哈希列表,类似于 HashMap,一个hash可以保存 2^23-1个数据
  • List:列表类型,类似于 LinkedList, 2^23-1
  • set:无序不重复的数据集合,类似于Set, 2^23-1
  • zset:(sorted set)有序不重复的数据集合, 2^23-1
Redis 的数据操作
  • 操作 string

    设置数据:set key value  比如: set username zhangsan
    获取数据: get key     比如: get username
    删除数据: del key         比如: del username
    
  • 操作 hash

    添加数据: hset key field value   比如: hset user username coco
    获取数据: hget key field      比如: hget user username
    删除数据: hdel key field      比如: hdel user username
    获取所有: hgetall key         比如: hgetall user
    
  • 操作 List

    添加数据: 
      从左边压入数据: lpush key value1 value2...
      从右边压入数据:rpush key value1 value2...
    弹出数据:
        从左边弹出数据:lpop key
        从右边弹出数据:rpop key
    查看数据:
    lrange key 0 -1     其中:-1表示最后一个数据
    
  • 操作 Set

    添加数据: sadd key value
    随机取出一个数据: srandmember key
    查看数据: smembers key
    删除数据: srem key member
    
    多集合之间的运算:
      交集: sinter key1 key2
      并集: sunion key1 key2
      差集: sdiff key1 key2
    
  • 通用的 key 操作

    查询key: keys表达式  比如:keys *, keys myset?
    删除key: del key
    判断key是否存在: exists key
    获取key的类型: type key
    

Jedis

Redis 在 web 应用开发中,是作为缓存来使用的,通过 Java 程序来操作 Redis 数据。
Jedis 操作 Redis 数据库需要的 jar 包:

  • Jedis-*.jar
  • common-pool*.jar u 连接池使用的

操作步骤:

  • 获取连接 Jedis 对象
  • 操作 Jedis
  • 释放资源,关闭 Jedis
Jedis 的 API
构造方法: Jedis(String host,int port)

常用方法: 方法名和命令名称一致
    设置string数据: set(String key,String value)
    获取string数据: get(String key)
    删除string数据: del(String key)
    从左边向list添加一个数据: lpush(String key,String value)
    
关闭连接: jedis.close();
Jedis 操作示例
@Test
public void demo1(){
    //1. 创建 Jedis 连接对象
    Jedis jedis = new Jedis("localhost",6379);

    //2. 操作 Redis 数据库
    //jedis.set("username","zhangsan");
    String username = jedis.get("username");
    System.out.println(username);

    //3. 关闭连接对象
    jedis.close();
}
Jedis 连接池的 API
连接池的构造方法:
    JedisPool(String host,int port)  使用默认配置的连接池
    JedisPool(JedisPoolConfig config,String host,int port) 使用自定义的连接池

连接池配置信息对象
    无参构造: JedisPoolConfig()
    常用方法:
        setMaxTotal(int maxTotal) 设置最大连接数
        setMaxIdle(int maxIdle) 设置最大空闲连接数
 
从连接池 JedisPool 里获取连接:
    Jedis jedis = pool.getResource()
Jedis 连接池示例
//1. 创建一个连接池配置信息对象,设置连接池的参数信息
//2. 使用配置信息对象,创建连接池对象
//3. 从连接池里获取连接
@Test
public void demo2() {
    // 创建一个连接池的配置对象
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxTotal(30);  //设置连接池里最多有30个连接
    jedisPoolConfig.setMaxIdle(10); //设置连接池里最多有10个空闲连接

    // 使用配置信息对象,创建连接池对象
    JedisPool jedisPool = new JedisPool(jedisPoolConfig, "localhost", 6379);

    //从连接池获取连接对象
    Jedis jedis = jedisPool.getResource();

    //操作 Redis 数据库
    String username = jedis.get("username");
    System.out.println(username);

    //关闭连接对象
    jedis.close();
}
封装 jedis 工具类 : JedisUtils
//1.JedisUtils

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ResourceBundle;

public class JedisUtils {

    private static JedisPool pool;

    private static String host;
    private static int port;
    private static int maxTotal;
    private static int maxIdle;

    static{
        //加载资源文件
        ResourceBundle bundle = ResourceBundle.getBundle("jedis");
        host = bundle.getString("host");
        port = Integer.parseInt(bundle.getString("port"));
        maxTotal = Integer.parseInt(bundle.getString("maxTotal"));
        maxIdle = Integer.parseInt(bundle.getString("maxIdle"));

        //创建连接池配置信息
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(maxTotal);
        config.setMaxIdle(maxIdle);

        //创建连接池对象
        pool = new JedisPool(config, host, port);
    }

    /**
     * 获取Jedis连接
     * @return Jedis对象
     */
    public static Jedis getJedis(){
        return pool.getResource();
    }

    /**
     * 关闭Jedis连接
     * @param jedis 要关闭的Jedis连接对象
     */
    public static void close(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    /**
     * 设置缓存
     * @param key 缓存的key
     * @param value 缓存的value
     */
    public static void setCache(String key, String value){
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.set(key, value);
        } catch (Exception e) {
            System.out.println("设置缓存数据失败:["+key+":"+value+"]");
        } finally {
            //关闭连接
            if (jedis != null) {
                jedis.close();
            }
        }
    }

    /**
     * 获取缓存
     * @param key 缓存的key
     * @return 缓存的value
     */
    public static String getCache(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.get(key);
        } catch (Exception e) {
            System.out.println("获取缓存失败:" + key);
        } finally {
           //关闭连接
            if (jedis != null) {
                jedis.close();
            }
        }
        return null;
    }
}

//2. 配置文件 jedis.properties
host=localhost
port=6379
maxTotal=30
maxIdle=10
    
//3.test
@Test
public void demo2() {
    JedisUtils.setCache("username", "coco1");
}

@Test
public void demo3() {
    String username = JedisUtils.getCache("username");
    System.out.println(username);
}

持久化机制

​ Redis数据库是把数据保存在了内存当中,那么如果Redis服务关闭,就需要把内存里的数据进行持久化保存,所以Redis本身提供了持久化机制:在某些时候把内存里的数据保存到磁盘文件上。

​ Redis提供了两种持久化机制:RDB模式 和 AOF模式。

RDB 模式
RDB 模式:快照模式,默认是开启状态的。

定期把 Redis 内存中的数据,生成快照文件,保存到磁盘文件上。默认生成的文件:dump.rdb,默认保存在 Redis 安装目录中

RDB 模式的相关配置,在 redis.conf里
save 900 1 表示:如果数据变更1次,那么900秒生成一次快照文件
save 300 10  表示:如果数据变更10次,那么300秒生成一次快照文件
save 60 10000 表示:如果数据变更1000次,那么10000秒生成一次快照文件

dbfilename dump.rdb   默认生成的快照文件名称
dir ./             表示生成的快照文件,保存到redis-server的当前目录
AOF 模式
AOF模式:append only file模式,默认是关闭的。
如果我们在Redis里执行数据的变更,那么每次变量,Redis都会把执行的命令追加到一个文件里。等Redis重启、需要恢复数据的时候,读取文件里所有的命令,按顺序重新构建Redis的数据。

如果开启了AOF模式,Redis会把数据变更的命令保存到了appendonly.aof,默认在Redis的安装目录里。这些信息可以通过修改redis.conf更改配置:

appendonly no     AOF模式的开关,默认是关闭状态,如果要使用,需要手动更改成yes。需要重新Redis
appendfilename "appendonly.aof"   默认生成的文件名称appendonly.aof

# appendfsync always     每次数据变更,都保存变更的命令到aof文件里
appendfsync everysec     每秒保存一次
# appendfsync no          不保存
RDB模式和AOF模式的优缺点

RDB模式:默认开启,性能高;但是可能会丢失数据
AOF模式:默认关闭,比较安全,丢失数据的可能性小;影响性能。

Redis在web应用里的使用方式

web应用里的数据最终还是必须要保存到关系型数据库里,Redis作为数据的缓存使用。


Redis在web应用里的使用方式.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272