Redis入门笔记

NoSQL的概述

什么是NoSQL

  • Not Only Sql
  • 非关系型数据库

为什么需要NoSQL

  • High performance -- 高并发读写
  • Huge Storage -- 海量数据的高效率存储与访问
  • High Scalability && High Availablity -- 高可扩展和高可用

NoSQL产品

  • Redis
  • MongoDB
  • membase

NoSQL数据库的四大分类

  • 键值(K-V)存储:快速查询,数据没有结构化
  • 列存储(Hbase):查找速度快,扩展强,功能局限
  • 文档数据库(MongoDB):数据结构要求不严格,查询性能不是很高,缺少统一查询的语法
  • 图形数据库(Neo4j,infinite):利用图结构的算法,需要的整个图做计算才能拿到结果,不利于分布式的部署

NoSQL特点

  • 易扩展,非关系型
  • 灵活的数据模型
  • 大量数据,高性能
  • 高可用

Redis

高性能键值对数据库,使用C语言开发,支持的数据类型如下:

  • 字符串类型
  • 列表类型
  • 有序集合类型
  • 散列类型
  • 集合类型

读写性能:50个并发程序执行10万个请求,读速度:100000次/秒 写速度:81000次/秒

Redis应用场景

  • 缓存
  • 任务队列
  • 网站访问统计
  • 数据过期处理
  • 应用排行榜
  • 分布式集群架构中的session分离

redis安装

自行google或者百度

Jedis入门

什么是jedis ?
Jedis官方github,readme介绍如下:

Jedis is a blazingly small and sane Redis java client.
Jedis was conceived to be EASY to use.
Jedis is fully compatible with redis 2.8.x and 3.x.x.

Jedis是一个超级炫酷轻量和智能与一体的Redis的Java客户端,大家都觉得Jedis非常的好用,并且完全的兼容Redis2.8.x and 3.x.x.与此同时,Jedis也是Redis官方推荐使用的Redis的Java客户端。

Jedis的基本使用

 @Test
    /**
     * jedis 单例测试
     */
    public void demo1() {
        // 1.设置ip地址和端口
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        // 2.保存数据
        jedis.set("name", "hello");
        // 3.获取数据
        String v = jedis.get("name");
        System.out.println(v);
        // 4.释放资源
        jedis.close();

    }

    @Test
    /**
     * 使用jedis连接池
     */
    public void demo2() {
        //创建jedis连接池配置对象:
        JedisPoolConfig config = new JedisPoolConfig();
        //配置jedisPoolConfig
        config.setMaxTotal(30);
        config.setMaxIdle(10);
        //创建jedis连接池
        JedisPool jedisPool = new JedisPool(config, "127.0.0.1", 6379);
        //使用连接池获取核心对象:
        Jedis jedis = null;
        try {
            //获取对象
            jedis = jedisPool.getResource();
            //设置数据
            jedis.set("name", "hashMap");
            //获取数据
            String value = jedis.get("name");
            System.out.println(value);

        } catch (Exception e) {
            System.out.println(e.getMessage());

        } finally {
            //释放资源
            if (jedis != null) {
                jedis.close();
            }
            if (jedisPool != null) {
                jedisPool.close();
            }
        }
    }

Redis数据结构

  • 字符串(String)常用
  • 哈希(hash)常用
  • 字符串列表(list)
  • 字符串集合(set)
  • 有序字符串集合(sorted list)

key的定义注意点:

  • 不要太长,占用内容大,且查找效率降低
  • 不要太短,否则降低可读性

存储String

以二进制的形式进行存储操作的,意味着String的存储和获取的结果是相同的
最多容纳的value:512M

存储String的常用命令:
  • 赋值
  1. set key value
  2. getset key newvalue
    --> 先获取key的值然后将key对应的value设置为newvalue
  • 取值
  1. get key
    --> 获取这个key对应的value
  • 删除
  1. del key
    --> 返回一个(interger)1表示删除成功,之后get key
    --> 会得到(nil)表示这个key没有value
  • 数值增减
  1. incr num
    --> 如果num不存在初始化为0然后加1,num变为1
    --> 如果num存在并且可以转为整形,num直接加1
    --> 如果num存在但是不能转为整形,报出错误信息

  2. decr num
    --> 如果num不存在初始化为0然后减1,num变为-1
    --> 如果num存在并且可以转为整形,num直接减1
    --> 如果num存在但是不能转为整形,报出错误信息

  • 扩展命令
  1. incrby num increment
    --> 如果num不存在初始化为0然后减increment
    --> 如果num存在并且可以转为整形,num直接减increment
    --> 如果num存在但是不能转为整形,报出错误信息

  2. decrby num decrement
    --> 如果num不存在初始化为0然后减decrement
    --> 如果num存在并且可以转为整形,num直接减decrement
    --> 如果num存在但是不能转为整形,报出错误信息

  3. append num value
    --> 如果num不存在新创建一个num value
    --> 如果num存在,以字符串形式在num后面追加一个value,得到追加之后的长度,结果是"numvalue"

存储Hash

hash类型可以看做是String key 和String value的map容器,非常适合存储值对象的信息,比如同户名,密码,年龄等...

存储hash常用的命令:
  • 赋值
  1. hset myset key value
    --> 设置 myset 指定的哈希集中指定字段key的值。
    --> 如果 myset 指定的哈希集不存在,会创建一个新的哈希集并与 myset 关联。
    --> 如果字段在哈希集中存在,它将被重写

  2. hmset myset key value [key value ...]
    --> 设置 myset 指定的哈希集中指定字段的值。该命令将重写所有在哈希集中存在的字段
    --> 如果 myset 指定的哈希集不存在,会创建一个新的哈希集并与 myset 关联

  • 取值
  1. hget myset key
    --> 返回 myset 指定的哈希集中该key所关联的值

  2. hmget myset key [key ...]
    --> 设置 myset 指定的哈希集中指定key的值。该命令将重写所有在哈希集中存在的字段。
    --> 如果 myset 指定的哈希集不存在,会创建一个新的哈希集并与 myset 关联

  3. hgetall myset
    --> 返回 key 指定的哈希集中所有的字段和值。返回值中,每个字段名的下一个是它的值,所以返回值的长度是哈希集大小的两倍

  • 删除
  1. hdel myset key [key ...]
    --> 从 key 指定的哈希集中移除指定的域。在哈希集中不存在的域将被忽略
    --> 如果 key 指定的哈希集不存在,它将被认为是一个空的哈希集,该命令将返回0

  2. del myset
    --> 直接删除整个哈希集

  • 增加数字
  1. hincreby myhash key increment
    增加 myhash 指定的哈希集中指定字段的数值。如果 myhash不存在,会创建一个新的哈希集并与 myhash 关联。如果字段不存在,则字段的值在该操作执行前被设置为 0

HINCRBY 支持的值的范围限定在 64位 有符号整数

  • 自学命令
  1. hexists myhash key
    判断key是否在myhash中存在。存在返回1,否则返回0

  2. hlen myhash
    返回 myhash 指定的哈希集包含的字段的数量。

  3. hkeys myhash
    返回 myhash 指定的哈希集中所有字段的key。

  4. hvals myhash
    返回 myhash 指定的哈希集中所有字段的value。

存储list:

  • ArrayList使用数字方式存储
  • LinkedList使用双向链表方式存储
  • 双向链表中增加数据
  • 双向链表中删除数据

存储list常用的命令:

  • 两端添加
  1. lpush
  2. rpush
  • 查看链表
  1. lrange
  • 两端弹出
  1. lpop
  2. rpop
  • 获取列表元素个数
  1. llen
  • 扩展命令
  1. lpushx
  2. rpushx
  3. lrem
  4. lset
  5. linsert
  6. rpoplpush --> 消息队列

存储Set

  • 和list类型不同的是,Set集合中不允许出现重复的元素
  • Set可以包含的元素数量是4294967295

存储Set常用的命令:

  • 添加删除元素
  1. sadd myset 1 2 3
  2. srem myset 2
  • 获取集合中的元素
  1. smembers myset --> 获取所有元素
  2. sismember myset 3 -> 判断某个元素时候属于集合
  • 集合中的差集运算
  1. sdiff
  • 集合中的并集运算
  1. sunion
  • 集合中的交集运算
  1. sinter
  • 扩展命令
  1. scard -> 获取元素个数
  2. srandmember myset -> 随机返回myset中的某个成员
  3. sdiffstore my1 my2 my3-> 把my2 my3差集存在my1中
  4. sinterstore my1 my2 my3 -> 把my2 my3 交集存在my1中
  5. sunionstore my1 my2 my3 -> 把my2 my3 并集存入my1中

存储Set使用的场景

  • 跟踪一些唯一性数据
  • 用于维护数据对象之间的关联关系,可以做一些并集交集的运算

存储Sorted-Set

  • 与Set的区别:
  1. Sorted-Set成员有序,时间复杂度是元素个数的对数O(logn)
  2. Sorted-Set中的成员在集合中的位置是有序的

存储Sorted-Set常用的命令:

  • 添加元素
  1. zadd mysort 50 funi 60 sorw
  • 删除元素
  1. zrem mysort funi sorw -> 删除sorted-set中的funi sorw记录
  • 获取元素
  1. zscore mysort funi -> 获取具体元素的分数
  2. zcard mysort -> 获取mysort的元素个数
  • 范围查询
  1. zrange mysort 0 -1 -> 显示所有元素(不显示分数)
  2. zrange mysort 0 -1 withscores -> 显示所有元素并显示分数,由小到大排序
  3. zrevrange mysort 0 -1 withscores -> 显示所有元素并显示分数,由大到小排序
  4. zremrangebyrank mysort 0 4 -> 按照下标顺序删除元素
  5. zremrangebyscore mysort 80 100 -> 按照分数的范围删除元素
  • 扩展命令
  1. zrangebyscore mysort 0 100 [withscores][limit 0 2]-> 显示分数为0到100并按照从小到大排序显示,withscore显示分数,limit显示从第0个到第2个
  2. zincrby mysort 3 li -> 给li的分数加3
  3. zcount mysort 80 90 -> 显示分数是80到90的元素个数

Sorted-Set使用场景

  • 大型在线游戏积分排行榜
    先使用zadd添加,然后zrange获取
  • 构建索引数据

Keys的通用操作

  • keys * -> 获取所有的key
  • del -> 删除key
  • exists -> 判断是否存在
  • get key -> 获取这个key的value
  • rename company newcompany -> 重命名company
  • expire newcompany 1000 -> 设置1000s的过期时间
  • ttl newcompany -> 过期时间剩余
  • type key -> 获取这个key的数据类型

Redis特性:

  1. 多数据库
  • 一个redis实例最多可以提供十六个数据库,就像是mysql的数据库一样,客户端可以指定连接那个数据库,redis的数据库下标是从0 - 15。
  • 可以使用select 1 -> 来选择几号数据库。默认使用的是0号数据库
  • 可以使用move myset 1 -> 将myset移动到1号数据库
  1. 支持事务
    Redis使用multi exec discard来执行事务,事务中所有的命令都会被串行化执行,事务执行期间,redis不会为其他客户端提供服务,保证事务的原子性。与关系型数据库不同的是,redis事务中,如果某个命令执行失败,事务不会终止,而是继续执行后面的命令
  • 可以使用multi 来开启是一个事务 相当于start transaction
  • 通过exec相当于提交 相当于commit
  • 通过discard相当于回滚 相当于roolback

Redis的持久化

  • Redis的高效率源于Redis把数据都存储在内存当中,为了保证Redis在服务重启之后数据不丢失,就需要把Redis中的数据进行持久化(数据从内存同步到硬盘)。

持久化方式:

  1. RDB方式
  2. AOF方式

持久化使用的方式:

RDB方式
默认支持的,不需要设置。RDB方式就是在默认的时间间隔之后,将内存中的数据集快照写入到磁盘

AOF方式:
以日志的方式记录服务器所处理的每一个操作,在Redis服务器启动之初,会读取这个文件,然后重新构建,保证数据是完整的

无持久化:
通过配置禁用Redis持久化功能,这个时候Redis就是一个缓存的功能

同时使用RDB和AOF的方式:’
数据集快照+日志

Redis持久化的RDB方式

优势:

  1. 只有一个文件,对于文件备份而言很简单。
  2. 灾难恢复,RDB可以压缩文件之后转移个另一个服务器上
  3. 性能最大化,分叉出一些子进程,然后使用子进程来做持久化操作,可以极大的避免IO的影响
  4. 相比于AOF如果数据集很大,启动效率更高

劣势:

  1. 如果想保证数据的高可用性,是数据尽可能的不丢失RDB不是很好的选择,因为如果在系统定时持久化之前宕机,还没有来得及写数据,就会导致数据的丢失
  2. 由于RDB使用fork分叉来使用子进程完成数据的持久化操作,因此如果数据集很大,会导致整个服务器停止几百毫秒来等待持久化操作的完成。

配置:redis.conf

save 900 1 //表示每900s有一个key发生变化就会之久化一次
save 300 10 //每300s有10个key发生变化,会往硬盘上写一次
save 60 10000 //每60s有10000个key发生变化会写一次

保存在./dump.rdb

Redis持久化的AOF方式

优势:

  1. 更高的数据安全性。redis中提供了三种同步策略:每秒同步,每修改同步,和不同步;
  2. 对日志写入的过程是append追加的模式。因此就算宕机,也不会破坏已经写入的日志。如果写入一半的时候出现问题,也可以使用redis-cheak-aof这个工具来帮助我们解决数据一致性的问题
  3. 如果日志过大,redis会自动启动数据重写机制,以append的模式不断的写入老的磁盘文件当中,同时redis还会产生一个文件来记录此期间产生的修改命令。因此重写切换的时候还是可以保证数据的安全性。
  4. AOF包含的是格式清晰的日志文件,用于记录所有的修改操作。甚至可以通过这个文件来重建数据

劣势:

  1. AOF的文件比RDB的文件更大
  2. 同步策略的不同导致AOF运行的效率低于RDB

配置:redis.conf

appendonly no //默认不启动AOF
appendonly.aof //AOF文件

//同步方式:
# appendfsync always //每修改同步
# appendfsync everysec //每秒同步
# appendfsync no //不同步 

如果要使用AOF方式,应该首先修改第1行的appendonly 为yes;然后appendfsync为always保证数据的安全

参考:

https://github.com/xetorthio/jedis
https://redis.io/
https://redis.io/documentation
http://www.redis.cn/commands.html
https://www.imooc.com/learn/839

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

推荐阅读更多精彩内容

  • 超强、超详细Redis入门教程 转载2017年03月04日 16:20:02 16916 转载自: http://...
    邵云涛阅读 17,431评论 3 313
  • NOSQL类型简介键值对:会使用到一个哈希表,表中有一个特定的键和一个指针指向特定的数据,如redis,volde...
    MicoCube阅读 3,958评论 2 27
  • 写给20年后的自己: 教室里只有老师一个人在叽里咕噜讲个不停,哎,跟窗外的蝉一样聒噪。坐我旁边的室友已经睡着了,哈...
    散翎阅读 246评论 0 2
  • 今天我有一件好事和一件坏事,好事是:我捡了一条小狗,坏事是:今天下雨了。 今天下雨了我感觉很不好很...
    谷殿艳阅读 112评论 0 0
  • 生活中,有这样两种截然相反的人。 有人生怕别人舒服,尽量让别人不舒服,而只要自己舒服就行。 还有一类人生怕别人不舒...
    你笑得很明媚阅读 335评论 2 1