参考:【itheima】
[TOC]
1 redis介绍
1.1 什么是redis
1 | — redis是一个nosql数据库(非关系型数据库) |
1.2 redis应用领域
1 | - 分布式缓存 |
1.3 关系型和非关系型数据库
为什么关系型(mysql)数据库适应不了互联网(高并发,数据量大)?
1 | - 因为硬盘的读取速度是硬伤;内存虽快,但容量小,且断电了内容就没了; |
— 参考阅读:
关系型数据库的不足:http://blog.sina.com.cn/s/blog_5755b8ed01017oor.html
全面梳理关系型数据库和 NoSQL 的使用情景:https://www.oschina.net/news/71132/nosql-use-case
2 redis安装运行
2.1 redis安装环境
1 | - redis是C语言开发,建议在linux上运行 |
2.2 redis安装步骤
版本: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
后端启动:
1 | - 将redis源码包(redis-4.0.9)里的redis.conf拷贝到redis安装路径的bin目录下 |
启动:./redis-server redis.conf
关闭:./redis-cli shutdown
ps:shutdown命令会先保存未保存的数据,再关闭。拒绝暴力关闭,会丢数据。
bug:解决远程无法连接redis服务端问题
- 首先开启6379端口
如果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.13> 然后重启redis
./redis-cli shutdown./redis-server redis.conf3> 再查看:ps -ef | grep redis
machine 15026 1 0 23:55 ? 00:00:00 ./**redis**-server *:6379*表示允许其他机子访问了
如果报错:
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介绍
1 | - 用来操作操作redis的jar。相当于使用JDBC操作SQL |
3.2 jedis使用
jar包
1 | <dependency> |
基本操作
1 | public class JedisTests { |
有bug就参见上一节:【bug:解决远程无法连接redis服务端问题】
4 redis数据类型
4.1 字符串String
命令
赋值
Code1
2
3SET key value
127.0.0.1:6379> set test 123
OK
取值
Code1
2
3GET key
127.0.0.1:6379> get test
"123“ps:当键不存在时返回空结果
删除
Code1
2
3Del key
127.0.0.1:6379> del test
(integer) 1数值增减
Code1
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的问题
1 | 假设有User对象以JSON序列化的形式存储到Redis中,User对象有id,username、password、age、name等属性,存储的过程如下: |
redis hash介绍
hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。一个对象转换成hashmap存放在redis中
应用场合:一般应用于将redis作为分布式缓存,存储数据库中的数据对象。
命令
赋值
Code1
2
3
4
5
6
7
8HSET 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
-----------------------------取值
Code1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17HGET 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.删除字段
Code1
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增加数字
Code1
2
3
4
5HINCRBY 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}’
命令
向列表两端增加元素
Code1
2
3
4
5
6
7
8LPUSH 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查看列表
Code1
2
3
4
5
6LRANGE key start stop
LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。
127.0.0.1:6379> lrange list1 0 2
1) "2"
2) "1"
3) "4"从列表两端弹出元素
Code1
2
3
4
5
6
7LPOP key
RPOP key
LPOP命令从列表左边弹出一个元素,会分两步完成,第一步是将列表左边的元素从列表中移除,第二步是返回被移除的元素值。
127.0.0.1:6379> lpop list1
"3“
127.0.0.1:6379> rpop list1
"6“获取列表中元素的个数
Code1
2
3LLEN key
127.0.0.1:6379> llen list1
(integer) 2
4.4 集合Set
redis set介绍
在集合中的每个元素都是不同的,且没有顺序。
命令
增加/删除元素
Code1
2
3
4
5
6
7
8SADD 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获得集合中的所有元素
Code1
2
3
4SMEMBERS key
127.0.0.1:6379> smembers set
1) "b"
2) "a”判断元素是否在集合中,无论集合中有多少元素都可以极速的返回结果。
Code1
2
3
4
5SISMEMBER key member
127.0.0.1:6379> sismember set a
(integer) 1
127.0.0.1:6379> sismember set h
(integer) 0集合的差集运算A-B
属于A并且不属于B的元素构成的集合
Code1
2
3
4
5
6
7
8
9SDIFF 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"集合的交集运算A ∩ B
属于A且属于B的元素构成的集合
Code1
2
3
4SINTER key [key ...]
127.0.0.1:6379> sinter setA setB
1) "2"
2) "3"集合的并集运算A ∪ B
属于A或者属于B的元素构成的集合
Code1
2
3
4
5
6SUNION 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介绍
有序集合与列表对比
1 | 在某些方面有序集合和列表类型有些相似。 |
应用场景:排行榜
根据商品销售量对商品进行排行显示,定义sorted set集合,商品销售量为元素的分数。
定义商品销售排行榜key:items:sellsort
1 | 写入商品销售量: |
命令
增加元素
Code1
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"删除元素
Code1
2
3
4
5
6ZREM key member [member ...]
移除有序集key中的一个或多个成员,不存在的成员将被忽略。
当key存在但不是有序集类型时,返回一个错误。
127.0.0.1:6379> zrem scoreboard lisi
(integer) 1获得排名在某个范围的元素列表
Code1
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命令
1 | 返回满足给定pattern 的所有key |
服务器命令
ping
1 | 测试连接是否存活 |
6 redis持久化方案
Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。
Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或将二者结合使用。
1 | RDB:间隔一段时间就保存 |
7 主从复制
备份机制,通过redis的主从复制机制就可以避免这种单点故障


