avatar

目录
redis学习笔记

参考:【itheima】

[TOC]

1 redis介绍

1.1 什么是redis

Code
1
2
3
— redis是一个nosql数据库(非关系型数据库)
— 关系型:以二维表形式存储数据
— 非关系型数据库:以键值队形式存储数据(key,value形式)

1.2 redis应用领域

Code
1
2
3
- 分布式缓存
- 分布式sesson:分布式集群的时候,一个服务器就是一个session,那么用户登录后session如何在系统中流转?使用redis
- 保存博客或论坛回复等。总之用在数据量大,并发量高的情况下。

1.3 关系型和非关系型数据库

为什么关系型(mysql)数据库适应不了互联网(高并发,数据量大)?

Code
1
2
3
4
5
- 因为硬盘的读取速度是硬伤;内存虽快,但容量小,且断电了内容就没了;
- redis就是把数据存在内存里,因为快,所以广泛应用于互联网项目;
- redis优点:存取快,官方称读取可达30万次每秒,写在10万次每秒,具体限制于硬件。
- redis缺点:对持久化支持不良好(内存)
- 总结:所以redis都不会单独使用(一般和关系型数据库配套使用,作为缓存功能)

— 参考阅读:

​ 关系型数据库的不足:http://blog.sina.com.cn/s/blog_5755b8ed01017oor.html

​ 全面梳理关系型数据库和 NoSQL 的使用情景:https://www.oschina.net/news/71132/nosql-use-case

2 redis安装运行

2.1 redis安装环境

Code
1
2
- redis是C语言开发,建议在linux上运行
- linux上需要C编译器,安装gcc环境

2.2 redis安装步骤

  • 源码下载:http://download.redis.io/releases/

  • 版本:redis-4.0.9.tar.gz

  • 上传:sfpt

    解压:tar -zxvf redis-4.0.9.tar.gz

  • 进入解压后的目录进行编译:make

    安装到指定目录:make PREFIX=/home/machine/redis install

    在该目录下会出现一个bin文件,redis-cli:客户端,redis-server:服务端

  • 前端启动服务端:./redis-server

    启动客户端:./redis-cli 出现 127.0.0.1:6379> 表示已连接到redis服务端

  • 客户端使用:set key1 1;get key1;

2.3 redis启动

前端启动:./redis-server

后端启动:

Code
1
2
3
4
5
- 将redis源码包(redis-4.0.9)里的redis.conf拷贝到redis安装路径的bin目录下
cp redis.conf /home/machine/redis/bin/
- 修改bin/redis.conf:将daemonize no 改为 daemonize yes
- 启动:./redis-server redis.conf
- redis默认使用6379端口,在redis.conf中修改,修改防火墙配置开放6379端口

启动:./redis-server redis.conf

关闭:./redis-cli shutdown

ps:shutdown命令会先保存未保存的数据,再关闭。拒绝暴力关闭,会丢数据。

bug:解决远程无法连接redis服务端问题

  1. 首先开启6379端口
  1. 如果telnet无法访问6379:

    1> 查看redis进程:ps -ef | grep redis

    machine 14973 1 0 23:34 ? 00:00:00 ./redis-server 127.0.0.1:6379

    发现只有本机127.0.0.1能使用,telnet连不通6379

    2> 因为在redis.conf中有个配置 bind 127.0.0.1 这个是默认只有本机访问,把这个注释掉就好了

    # bind 127.0.0.1

    3> 然后重启redis

    ./redis-cli shutdown

    ./redis-server redis.conf

    3> 再查看:ps -ef | grep redis

    machine 15026 1 0 23:55 ? 00:00:00 ./**redis**-server *:6379

    *表示允许其他机子访问了

  2. 如果报错:redis.clients.jedis.exceptions.JedisDataException: DENIED Redis is running in protected mode because protected mode is enabled

    修改redis.conf ,将protected-mode yes 改为 protected-mode no,重启服务

3 jedis

3.1 jedis介绍

Code
1
2
- 用来操作操作redis的jar。相当于使用JDBC操作SQL
- github:https://github.com/xetorthio/jedis

3.2 jedis使用

jar包

Code
1
2
3
4
5
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>

基本操作

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class JedisTests {

//快速开始
@Test
public void test01(){

//创建客户端,连接redis服务端
Jedis jedis = new Jedis("10.211.55.6", 6379);

//存取数据
jedis.set("key2","2");
String key2 = jedis.get("key2");
System.out.println(key2);

//关闭连接
jedis.close();

}

//连接池
@Test
public void testJedisPool(){
//创建连接池
JedisPool jedisPool = new JedisPool("10.211.55.6", 6379);
//获取连接
Jedis jedis = jedisPool.getResource();
//存取
String key2 = jedis.get("key2");
System.out.println(key2);
//关闭连接,会自动放回池子供别人使用,否则,连接耗尽就
jedis.close();
//关闭连接池
jedisPool.close();
}
}

有bug就参见上一节:【bug:解决远程无法连接redis服务端问题】

4 redis数据类型

4.1 字符串String

命令

  1. 赋值

    Code
    1
    2
    3
    SET key value
    127.0.0.1:6379> set test 123
    OK
  1. 取值

    Code
    1
    2
    3
    GET key
    127.0.0.1:6379> get test
    "123“

    ps:当键不存在时返回空结果

  2. 删除

    Code
    1
    2
    3
    Del key
    127.0.0.1:6379> del test
    (integer) 1
  3. 数值增减

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    - 递增数字
    INCR key
    当存储的字符串是整数时,Redis提供了一个实用的命令INCR,其作用是让当前键值递增,并返回递增后的值。
    127.0.0.1:6379> incr key1
    (integer) 1
    127.0.0.1:6379> incr key1
    (integer) 2
    127.0.0.1:6379> incr key1
    (integer) 3

    - 递减数值
    DECR key

    - 增加指定的整数
    INCRBY key increment
    示例:
    127.0.0.1:6379> incrby key1 2
    (integer) 5
    127.0.0.1:6379> incrby key1 2
    (integer) 7
    127.0.0.1:6379> incrby key1 2
    (integer) 9

4.2 散列Hash

使用string的问题

Code
1
2
3
4
假设有User对象以JSON序列化的形式存储到Redis中,User对象有id,username、password、age、name等属性,存储的过程如下: 
保存、更新:
User对象 > json(string) > redis
如果在业务上只是更新age属性,其他的属性并不做更新我应该怎么做呢? 如果仍然采用上边的方法在传输、处理时会造成资源浪费,下边讲的hash可以很好的解决这个问题。

redis hash介绍

hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。一个对象转换成hashmap存放在redis中

应用场合:一般应用于将redis作为分布式缓存,存储数据库中的数据对象。

命令

  1. 赋值

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    HSET key field value	一次只能设置一个字段值
    127.0.0.1:6379> hset user username zhangsan
    (integer) 1
    -----------------------------
    HMSET key field value [field value ...] 一次可以设置多个字段值
    127.0.0.1:6379> hmset user age 20 username lisi
    OK
    -----------------------------
  2. 取值

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    HGET key field			一次只能获取一个字段值
    127.0.0.1:6379> hget user username
    "zhangsan“
    -----------------------------
    HMGET key field [field ...] 一次可以获取多个字段值
    127.0.0.1:6379> hmget user age username
    1) "20"
    2) "lisi"
    -----------------------------
    HGETALL key
    127.0.0.1:6379> hgetall user
    1) "age"
    2) "20"
    3) "username"
    4) "lisi"
    -----------------------------
    HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0.
  3. 删除字段

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    可以删除一个或多个字段,返回值是被删除的字段个数 
    HDEL key field [field ...]
    127.0.0.1:6379> hdel user age
    (integer) 1
    127.0.0.1:6379> hdel user age name
    (integer) 0
    127.0.0.1:6379> hdel user age username
    (integer) 1
  4. 增加数字

    Code
    1
    2
    3
    4
    5
    HINCRBY key field increment
    127.0.0.1:6379> hincrby user age 2 将用户的年龄加2
    (integer) 22
    127.0.0.1:6379> hget user age 获取用户的年龄
    "22“

4.3 列表List

ArrayList与LinkedList的区别

​ ArrayList使用数组方式存储数据,所以根据索引查询数据速度快,而新增或者删除元素时需要设计到位移操作,所以比较慢。

​ LinkedList使用双向链接方式存储数据,每个元素都记录前后元素的指针,所以插入、删除数据时只是更改前后元素的指针指向即可,速度非常快,然后通过下标查询元素时需要从头开始索引,所以比较慢,但是如果查询前几个元素或后几个元素速度比较快。

redis list介绍

​ 列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。

​ 列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。

应用场景:评论列表

思路:在redis中创建商品评论列表。用户发布商品评论,将评论信息转成json存储到list中。用户在页面查询评论 列表,从redis中取出json数据展示到页面。

定义商品评论列表key:商品编号为1001的商品评论key:items: comment:1001

192.168.101.3:7001> LPUSH items:comment:1001’{“id”:1,”name”:”商品不错,很好!!”,”date”:1430295077289}’

命令

  1. 向列表两端增加元素

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    LPUSH key value [value ...]
    RPUSH key value [value ...]
    向列表左边增加元素
    127.0.0.1:6379> lpush list1 1 2 3
    (integer) 3
    向列表右边增加元素
    127.0.0.1:6379> rpush list1 4 5 6
    (integer) 3
  2. 查看列表

    Code
    1
    2
    3
    4
    5
    6
    LRANGE key start stop
    LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。
    127.0.0.1:6379> lrange list1 0 2
    1) "2"
    2) "1"
    3) "4"
  3. 从列表两端弹出元素

    Code
    1
    2
    3
    4
    5
    6
    7
    LPOP key
    RPOP key
    LPOP命令从列表左边弹出一个元素,会分两步完成,第一步是将列表左边的元素从列表中移除,第二步是返回被移除的元素值。
    127.0.0.1:6379> lpop list1
    "3“
    127.0.0.1:6379> rpop list1
    "6“
  4. 获取列表中元素的个数

    Code
    1
    2
    3
    LLEN key
    127.0.0.1:6379> llen list1
    (integer) 2

4.4 集合Set

redis set介绍

在集合中的每个元素都是不同的,且没有顺序。

命令

  1. 增加/删除元素

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    SADD key member [member ...]
    SREM key member [member ...]
    127.0.0.1:6379> sadd set a b c
    (integer) 3
    127.0.0.1:6379> sadd set a
    (integer) 0
    127.0.0.1:6379> srem set c d
    (integer) 1
  2. 获得集合中的所有元素

    Code
    1
    2
    3
    4
    SMEMBERS key
    127.0.0.1:6379> smembers set
    1) "b"
    2) "a”

    判断元素是否在集合中,无论集合中有多少元素都可以极速的返回结果

    Code
    1
    2
    3
    4
    5
    SISMEMBER key member
    127.0.0.1:6379> sismember set a
    (integer) 1
    127.0.0.1:6379> sismember set h
    (integer) 0
  3. 集合的差集运算A-B

    属于A并且不属于B的元素构成的集合

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SDIFF key [key ...]
    127.0.0.1:6379> sadd setA 1 2 3
    (integer) 3
    127.0.0.1:6379> sadd setB 2 3 4
    (integer) 3
    127.0.0.1:6379> sdiff setA setB
    1) "1"
    127.0.0.1:6379> sdiff setB setA
    1) "4"
  4. 集合的交集运算A ∩ B

    属于A且属于B的元素构成的集合

    Code
    1
    2
    3
    4
    SINTER key [key ...]
    127.0.0.1:6379> sinter setA setB
    1) "2"
    2) "3"
  5. 集合的并集运算A ∪ B

    属于A或者属于B的元素构成的集合

    Code
    1
    2
    3
    4
    5
    6
    SUNION key [key ...]
    127.0.0.1:6379> sunion setA setB
    1) "1"
    2) "2"
    3) "3"
    4) "4"

4.5 有序集合sorted set

redis sorted set介绍

有序集合与列表对比

Code
1
2
3
4
5
6
7
8
在某些方面有序集合和列表类型有些相似。 
1、二者都是有序的。
2、二者都可以获得某一范围的元素。
但是,二者有着很大区别:
1、列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。
2、有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快。
3、列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现)
4、有序集合要比列表类型更耗内存。

应用场景:排行榜

根据商品销售量对商品进行排行显示,定义sorted set集合,商品销售量为元素的分数。

定义商品销售排行榜key:items:sellsort

Code
1
2
3
4
5
6
7
8
9
写入商品销售量:
商品编号1001的销量是9,商品编号1002的销量是10
192.168.101.3:7007> ZADD items:sellsort9 1001 10 1002

商品编号1001的销量加1
192.168.101.3:7001> ZINCRBY items:sellsort 1 1001

商品销量前10名:
192.168.101.3:7001> ZRANGE items:sellsort 0 9 withscores

命令

  1. 增加元素

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。 
    ZADD key score member [score member ...]
    127.0.0.1:6379> zadd scoreboard 80 zhangsan 89 lisi 94 wangwu
    (integer) 3
    127.0.0.1:6379> zadd scoreboard 97 lisi
    (integer) 0
    获取元素的分数
    ZSCORE key member
    127.0.0.1:6379> zscore scoreboard lisi
    "97"
  2. 删除元素

    Code
    1
    2
    3
    4
    5
    6
    ZREM key member [member ...]
    移除有序集key中的一个或多个成员,不存在的成员将被忽略。
    当key存在但不是有序集类型时,返回一个错误。

    127.0.0.1:6379> zrem scoreboard lisi
    (integer) 1
  3. 获得排名在某个范围的元素列表

    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    获得排名在某个范围的元素列表 
    ZRANGE key start stop [WITHSCORES] 照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)

    127.0.0.1:6379> zrange scoreboard 0 2
    1) "zhangsan"
    2) "wangwu"
    3) "lisi“

    -----------------------------
    ZREVRANGE key start stop [WITHSCORES] 照元素分数从大到小的顺序返回索引从start到stop之间的所有元素(包含两端的元素)

    127.0.0.1:6379> zrevrange scoreboard 0 2
    1) " lisi "
    2) "wangwu"
    3) " zhangsan “

    -----------------------------
    如果需要获得元素的分数的可以在命令尾部加上WITHSCORES参数

    127.0.0.1:6379> zrange scoreboard 0 1 WITHSCORES
    1) "zhangsan"
    2) "80"
    3) "wangwu"
    4) "94"

5 redis其他命令

keys命令

Code
1
2
3
4
5
6
7
返回满足给定pattern 的所有key
redis 127.0.0.1:6379> keys mylist*
1) "mylist"
2) "mylist5"
3) "mylist6"
4) "mylist7"
5) "mylist8"

服务器命令

ping

Code
1
2
3
4
5
6
7
8
9
测试连接是否存活
redis 127.0.0.1:6379> ping
PONG
//执行下面命令之前,我们停止redis 服务器
redis 127.0.0.1:6379> ping
Could not connect to Redis at 127.0.0.1:6379: Connection refused
//执行下面命令之前,我们启动redis 服务器
not connected> ping
PONG

6 redis持久化方案

​ Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。

​ Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或将二者结合使用。

Code
1
2
3
4
5
6
7
RDB:间隔一段时间就保存
优点:快
缺点:断电之前来不及保存最后一次,数据丢失

AOF:一有变化就保存
优点:影响性能
缺点:不丢数据

7 主从复制

​ 备份机制,通过redis的主从复制机制就可以避免这种单点故障

文章作者: Machine
文章链接: https://machine4869.gitee.io/2018/06/04/15326723152601/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 哑舍
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论