1、Redis简介

对于一个稍有经验的程序员,都应知道:内存条的读写速度是远高于硬盘的读写速度的,而在以往的数据库中,我们往往以硬盘为主,这样导致了读写硬盘频繁,系统效率低下,而Redis则是以内存为主,读写都尽可能的发生在内存中。

举个例子:在刚开始学习Java语言的时候,小松还没学到数据库,可是他需要保存数据,于是自己写了一个文件管理API,供自己使用。(弱化版的数据库)

后来,他发现因为只是演示作用,所以根本不需要持久化,而且又对开发效率有很大要求,于是他直接使用了HashMap做存储。(将数据存储在HashMap中,HashMap的数据放在内存中,这就是一个弱化版的Redis)。

为了方便Java程序员理解,我推荐将 Redis 理解为一个大号的HashMap。

  1. HashMap是键值对,Redis的数据也是以键值对的形式存储。
  2. HashMap不支持线程安全,Redis则是单线程应用
  3. HashMap使用的是拉链法,Redis能存储List并对其操作。(强行理解)

你可以认为Redis就是C语言写出来的HashMap,并增加了远程访问,本地备份,主从复制等功能。

Redis的安装:

2、 为什么选择Redis

在简介中,我们提到了HashMap,其实在很多应用中HashMap就已经足够程序员优化数据了。

如果Redis就是一个大号的HashMap,那么为什么还需要Redis呢?

  • 这里的答案应该与“为什么我们不自己实现一个文件操作系统,而使用别人写好的数据库?”相同。
  • 别人写好的Redis支持了远程访问,本地备份,主从复制等等功能。
  • 自己的HashMap除了操作方便(其实就是懒得学Redis,学了Jedis后会发现其实差不多方便)。没啥其他优点了。
  • Redis是C语言写的,距离底层更近。(我没说C一定比Java快,Java是世界第一的语言)
  • Redis花了大把大把的代码做了HashMap做不到的功能,我们为什么要重复造轮子呢?

2.1 Redis的几个特性

Redis 的持久化

  1. 定期保存最新的Redis快照
  2. 将所有Redis操作都保存到一个文件中。
  3. 以上两种都是思想,实际上做了非常多的优化,这里不展开讲。

Redis的线程安全

  1. Redis是单线程应用,所以没有线程问题。
  2. 实际上,,Redis是有多线程的,不过绝大多数操作都是单线程,而上面的持久化就是一个多线程操作(持久化是一个只读操作)。

Redis的主从复制

  1. 最开始:执行复制的从服务器会连接上主服务器,接受主服务器发送的整个数据库的初始副本;
  2. 之后:所有主服务执行的写命令都会发送给从服务器,让他们执行写操作。
  3. 很明显,主从架构可以实现读写分离,提升系统效率。

3、Redis能存储什么?

在回答这个问题之前,我先随手提下Java中最常见的几个类。

redis 用lettuce 还是jedis_Java

几个小问题:

Q: 为什么八大基本类型只留下了两个?
> 	因为其他六个都可以用最基本的这两个表示,这两个的数据组织方式不同,所以不可以再删除。

Q: Set底层不是Map吗? 为什么还要保留?
> 	因为Redis能存储Set类型,我删了还怎么讲?

接下来画出来Redis能存储的数据结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gBeyOI3w-1577699124536)(C:\Users\Administrator\Pictures\Redis\Redis能存储的数据结构.png)]

redis 用lettuce 还是jedis_redis_02


Q: Redis不直接支持int和double?

对,Redis支持int和double,不过需要存入和取出时仍是String,当然你依然可以按照int来自增自减,而且其是原子操作。

4、Redis数据结构简介

先来一个没人会看的表格。

结构类型

结构存储的值

结构的读写能力

STRING

能存储string,int,double

字符串基本操作和自增自减操作

LIST

类比于:LinkedList< STRING >

支持双向队列操作,支持偏移量trimLIST

支持同时读取多个元素。

SET

类比于:Set< STRING >

支持Set的基本操作(增删改查去重)

HASH

类比于:HASHMAP< STRING>

增删查单个元素,获取所有键值对。

ZSET

有序集合,按照指定规则排序

增删查单个元素,根据规则获取相对的键值对们。

接下来涉及到Redis操作,请根据其他博客装上Redis后进行操作。

4.1 Redis中的字符串(STRING)

与其说是字符串,就是一个标准的HashMap<String,String>.

字符串首先是一个键值对形式,我们看看键值对的基础操作。

我们启动redis做一个演示.

127.0.0.1:6379> set hello world	# 放入键值对<hello, world>
OK # 操作成功
127.0.0.1:6379> get hello # 得到键为hello的value
"world"
127.0.0.1:6379> del hello # 删除key = hello
(integer) 1 # 影响元素的个数
127.0.0.1:6379> get hello	# 验证已删除
(nil)	# null

上述操作很简单,也无需介绍,除这些以外,redis提供了许多对字符串的操作。不过这些内容我们等到后面专门的章节进行讲述。

4.2 Redis中的列表(LIST)

相当于HashMap<String,LinkedList< String>>.

列表相对于STRING来说,增加了许多操作,比如两端都可以进入和抛出,还可以打印下标位于(left,right)的元素。

直接上操作.

# 下面的意思是 从右侧依次放入 item,item2,item
# rpush = rightpush
127.0.0.1:6379> rpush list-key item
(integer) 1
127.0.0.1:6379> rpush list-key item2
(integer) 2
127.0.0.1:6379> rpush list-key item3
(integer) 3

# lrange 是打印下表属于 [start,stop]的所有元素。 -1为全部
127.0.0.1:6379> lrange list-key 0 -1
1) "item"
2) "item2"
3) "item3"

# get操作 lindex = 从left数的[i]个。
127.0.0.1:6379> lindex list-key 1
"item2"
# 抛出最左侧元素: lpop = leftpop;
127.0.0.1:6379> lpop list-key
"item"
# 验证是否
127.0.0.1:6379> lrange list-key 0 -1
1) "item2"
2) "item3"
127.0.0.1:6379>

4.3 Redis中的集合(SET)

相当于 HashMap<String, Set< String>>

直接上操作吧.

# set 添加操作,sadd = setAdd, 通俗易懂.
127.0.0.1:6379> sadd set-key item
(integer) 1
127.0.0.1:6379> sadd set-key item2
(integer) 1
127.0.0.1:6379> sadd set-key item3
(integer) 1
# set添加重复元素,自然会失败,所以return 0.
127.0.0.1:6379> sadd set-key item
(integer) 0
# 查看所有元素,顺序很玄学。
127.0.0.1:6379> smembers set-key
1) "item2"
2) "item3"
3) "item"
# 是否包含操作, sismember = setIsMember.询问是否是这个集合中的元素。
127.0.0.1:6379> sismember set-key item4
(integer) 0
127.0.0.1:6379> sismember set-key item
(integer) 1
# srem = set remove.删除元素.
127.0.0.1:6379> srem set-key item2
(integer) 1
127.0.0.1:6379> srem set-key item2
(integer) 0
# 查看所有元素.
127.0.0.1:6379> smembers set-key
1) "item3"
2) "item"

4.4 Redis的散列

相当于Java中的HashMap<String, HashMap<String, String>>

# hset = hash set《key,<key,value>》
127.0.0.1:6379> hset hash-key sub-key1 v1
(integer) 1
127.0.0.1:6379> hset hash-key sub-key2 v2
(integer) 1
127.0.0.1:6379> hset hash-key sub-key1 v1
(integer) 0
127.0.0.1:6379> hgetall hash-key
1) "sub-key1"
2) "v1"
# 其实,我觉得如果能打印成: "sub-key1"<--->"v1"就好了。
3) "sub-key2"
4) "v2"
# hdel = hash_delete
127.0.0.1:6379> hdel hash-key sub-key2
(integer) 1
127.0.0.1:6379> hget hash-key sub-key1
"v1"
127.0.0.1:6379> hgetall hash-key
1) "sub-key1"
2) "v1"
127.0.0.1:6379> hset hash-key sub-key1 v2
(integer) 0
127.0.0.1:6379> hgetall hash-key
1) "sub-key1"
2) "v2"

4.5 Redis的有序集合.

有序集合可以类比Java中的TreeMap,这个是字定义分数。

操作:

127.0.0.1:6379> zadd zset-key 728 m1
(integer) 1
127.0.0.1:6379> zadd zset-key 982 m0
(integer) 1
127.0.0.1:6379> zadd zset-key 982 m0
(integer) 0
127.0.0.1:6379> zrange zset-key 0 -1 withscores
1) "m1"
2) "728"
3) "m0"
4) "982"
127.0.0.1:6379> zrangebyscore  zset-key 0 800 withscores
1) "m1"
2) "728"
127.0.0.1:6379> zrem zset-key m1
(integer) 1
127.0.0.1:6379> zrem zset-key m1
(integer) 0
127.0.0.1:6379> zrange zset-key 0 -1 withscores
1) "m0"
2) "982"
127.0.0.1:6379>