Redis数据结构存储系统:第一章:安装配置

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

PONG

127.0.0.1:6379> exit

另一种:

cd /usr/local/redis/bin

./redis-cli -h 192.168.0.100 -p 6379

192.168.0.100:6379> ping

PONG

四、Redis五种常用数据结构

===============

1.总体结构


KEYVALUE
string
list
set
hash
zset

Redis中的数据,总体上是键值对,不同数据类型指的是键值对中值的类型。

2.string类型


Redis中最基本的类型,它是key对应的一个单一值。二进制安全,不必担心由于编码等问题导致二进制数据变化。所以redis的string可以包含任何数据,比如jpg图片或者序列化的对象。Redis中一个字符串值的最大容量是512M。

3.list类型


Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。说明它的底层是基于链表实现的,所以它操作时头尾效率高,中间效率低。

2.set类型


Redis的set是string类型的无序集合。它是基于哈希表实现的。

3.hash类型


本身就是一个键值对集合。可以当做Java中的Map<String,Object>对待。

4.zset类型


Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。

五、Redis命令行操作

========================================================================

1.基本操作


①切换数据库

``` html

Redis默认有16个数据库。

115 # Set the number of databases. The default database is DB 0, you can select

116 # a different one on a per-connection basis using SELECT where

117 # dbid is a number between 0 and ‘databases’-1

118 databases 16

使用select进行切换,数据库索引从0开始

127.0.0.1:6379> select 2

OK

127.0.0.1:6379[2]> select 0

OK

127.0.0.1:6379>

```

②查看数据库长度

``` html

127.0.0.1:6379> dbsize

(integer) 3

```

2.KEY操作

``` html

●KEYS PATTERN

●TYPE KEY

返回KEY对应的值的类型

●MOVE KEY DB

把一组键值对数据移动到另一个数据库中

●DEL KEY [KEY …]

根据KEY进行删除,至少要指定一个KEY

●EXISTS KEY

检查指定的KEY是否存在。指定一个KEY时,存在返回1,不存在返回0。可以指定多个,返回存在的KEY的数量。

●RANDOMKEY

在现有的KEY中随机返回一个

●RENAME KEY NEWKEY

重命名一个KEY,NEWKEY不管是否是已经存在的都会执行,如果NEWKEY已经存在则会被覆盖。

●RENAMENX KEY NEWKEY

只有在NEWKEY不存在时能够执行成功,否则失败

●TIME

返回当前UNIX时间戳

●TTL KEY

以秒为单位查看KEY还能存在多长时间

●PTTL KEY

以毫秒为单位查看KEY还能存在多长时间

●EXPIRE KEY SECONDS

给一个KEY设置在SECONDS秒后过期,过期会被Redis移除。

●EXPIREAT KEY TIMESTAMP

设置一个KEY在TIMESTAMP指定的时间过期

●PEXPIRE KEY MILLISECONDS

以毫秒为单位指定过期时间

●PEXPIREAT KEY MILLISECONDS-TIMESTAMP

以毫秒为单位指定过期的时间戳

●PERSIST KEY

移除过期时间,变成永久key

```

2.string操作

``` html

●SET KEY VALUE [EX SECONDS] [PX MILLISECONDS] [NX|XX]

给KEY设置一个string类型的值。

EX参数用于设置存活的秒数。

PX参数用于设置存活的毫秒数。

NX参数表示当前命令中指定的KEY不存在才行。

XX参数表示当前命令中指定的KEY存在才行。

●GET KEY

根据key得到值,只能用于string类型。

●APPEND KEY VALUE

把指定的value追加到KEY对应的原来的值后面,返回值是追加后字符串长度

●STRLEN KEY

直接返回字符串长度

●INCR KEY

自增1

●DECR KEY

自减1

●INCRBY KEY INCREMENT

原值+INCREMENT

●DECRBY KEY DECREMENT

原值-DECREMENT

●GETRANGE KEY START END

从字符串中取指定的一段

●SETRANGE KEY OFFSET VALUE

从offset开始使用VALUE进行替换

●SETEX KEY SECONDS VALUE

设置KEY,VALUE时指定存在秒数

●SETNX KEY VALUE

新建字符串类型的键值对

●MSET KEY VALUE [KEY VALUE …]

一次性设置一组多个键值对

●MGET KEY [KEY …]

一次性指定多个KEY,返回它们对应的值,没有值的KEY返回值是(nil)

●MSETNX KEY VALUE [KEY VALUE …]

一次性新建多个值

●GETSET KEY VALUE

设置新值,同时能够将旧值返回

```

3.list操作

``` html

●LPUSH key value [value …]

●RPUSH key value [value …]

●LRANGE key start stop

根据list集合的索引打印元素数据

正着数:0,1,2,3,…

倒着数:-1,-2,-3,…

●LLEN key

●LPOP key

从左边弹出一个元素。

弹出=返回+删除。

●RPOP key

从右边弹出一个元素。

●RPOPLPUSH source destination

从source中RPOP一个元素,LPUSH到destination中

●LINDEX key index

根据索引从集合中取值

●LINSERT key BEFORE|AFTER pivot value

在pivot指定的值前面或后面插入value

●LPUSHX key value

只能针对存在的list执行LPUSH

●LREM key count value

根据count指定的数量从key对应的list中删除value

●LSET key index value

把指定索引位置的元素替换为另一个值

●LTRIM key start stop

仅保留指定区间的数据,两边的数据被删除

```

4.set操作

``` html

●SADD key member [member …]

●SMEMBERS key

●SCARD key

返回集合中元素的数量

●SISMEMBER key member

检查当前指定member是否是集合中的元素

●SREM key member [member …]

从集合中删除元素

●SINTER key [key …]

将指定的集合进行“交集”操作

集合A:a,b,c

集合B:b,c,d

交集:b,c

●SINTERSTORE destination key [key …]

取交集后存入destination

●SDIFF key [key …]

将指定的集合执行“差集”操作

集合A:a,b,c

集合B:b,c,d

A对B执行diff:a

相当于:A-交集部分

●SDIFFSTORE destination key [key …]

●SUNION key [key …]

将指定的集合执行“并集”操作

集合A:a,b,c

集合B:b,c,d

并集:a,b,c,d

●SUNIONSTORE destination key [key …]

●SMOVE source destination member

把member从source移动到destination

●SPOP key [count]

从集合中随机弹出count个数量的元素,count不指定就弹出1个

●SRANDMEMBER key [count]

从集合中随机返回count个数量的元素,count不指定就返回1个

●SSCAN key cursor [MATCH pattern] [COUNT count]

基于游标的遍历

```

5.hash操作

``` html

●HSET key field value

●HGETALL key

●HGET key field

●HLEN key

●HKEYS key

●HVALS key

●HEXISTS key field

●HDEL key field [field …]

●HINCRBY key field increment

●HMGET key field [field …]

●HMSET key field value [field value …]

●HSETNX key field value

●HSCAN key cursor [MATCH pattern] [COUNT count]

```

6.zset操作

``` html

●ZADD key [NX|XX] [CH] [INCR] score member [score member …]

●ZRANGE key start stop [WITHSCORES]

●ZCARD key

●ZCOUNT key min max

根据分数在min,max之间查找元素

●ZSCORE key member

●ZINCRBY key increment member

●ZLEXCOUNT key min max

●ZRANGEBYLEX key min max [LIMIT offset count]

按照字母顺序在区间内返回member

min和max使用“[a”表示闭区间,使用“(a”表示开区间

-表示负无穷

+表示正无穷

●ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

在分数的指定区间内返回数据

●ZRANK key member

先对分数进行升序排序,返回member的排名

●ZREM key member [member …]

●ZREMRANGEBYLEX key min max

●ZREMRANGEBYRANK key start stop

●ZREMRANGEBYSCORE key min max

●ZREVRANGE key start stop [WITHSCORES]

●ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]

●ZREVRANK key member

●ZINTERSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]

●ZUNIONSTORE destination numkeys key [key …] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

把指定集合的member取交集,分数会相加

●ZSCAN key cursor [MATCH pattern] [COUNT count]

```

六、Redis持久化机制

============

官网描述

Redis工作时数据都存储在内存中,万一服务器断电,则所有数据都会丢失。针对这种情况,Redis采用持久化机制来增强数据安全性。

1.RDB


①机制描述

每隔一定的时间把内存中的数据作为一个快照保存到硬盘上的文件中。Redis默认开启RDB机制。

②触发时机

[1]基于默认配置

``` properties

save 900 1

save 300 10

save 60 10000

```

含义

| 配置 | 含义 |

| — | — |

| save 900 1 | 900秒内至少有一次修改则触发保存操作 |

| save 300 10 | 300秒内至少有10次修改则触发保存操作 |

| save 60 10000 | 60秒内至少有1万次修改则触发保存操作 |

[2]使用保存命令

save或bgsave

[3]使用flushall命令

这个命令也会产生dump.rdb文件,但里面是空的,没有意义

[4]服务器关闭

如果执行SHUTDOWN命令让Redis正常退出,那么此前Redis就会执行一次持久化保存。

③相关配置

| 配置项 | 取值 | 作用 |

| — | — | — |

| save | “” | 禁用RDB机制 |

| dbfilename | 文件名,例如:dump.rdb | 设置RDB机制下,数据存储文件的文件名 |

| dir | Redis工作目录路径 | 指定存放持久化文件的目录的路径。注意:这里指定的必须是目录不能是文件名 |

④思考

RDB机制能够保证数据的绝对安全吗?

2.AOF


①机制描述

根据配置文件中指定的策略,把生成数据的命令保存到硬盘上的文件中。一个AOF文件的内容可以参照下面的例子:

``` properties

*2

$6

SELECT

$1

0

*3

$3

set

$3

num

$2

10

*2

$4

incr

$3

num

*2

$4

incr

$3

num

*2

$4

incr

$3

num

```

生成上面文件内容的Redis命令是:

``` html

set num 10

incr num

incr num

incr num

```

②AOF基本配置

| 配置项 | 取值 | 作用 |

| — | — | — |

| appendonly | yes | 启用AOF持久化机制 |

|   | no | 禁用AOF持久化机制[默认值] |

| appendfilename | “文件名” | AOF持久化文件名 |

| dir | Redis工作目录路径 | 指定存放持久化文件的目录的路径。注意:这里指定的必须是目录不能是文件名 |

| appendfsync | always | 每一次数据修改后都将执行文件写入操作,缓慢但是最安全。 |

|   | everysec | 每秒执行一次写入操作。折中。 |

|   | no | 由操作系统在适当的时候执行写入操作,最快。 |

③AOF重写

对比下面两组命令:

| AOF重写前 | AOF重写后 |

| — | — |

| set count 1

incr count

incr count

incr count | set count 4 |

两组命令执行后对于count来说最终的值是一致的,但是进行AOF重写后省略了中间过程,可以让AOF文件体积更小。而Redis会根据AOF文件的体积来决定是否进行AOF重写。参考的配置项如下:

| 配置项 | 含义 |

| — | — |

| auto-aof-rewrite-percentage 100 | 文件体积增大100%时执行AOF重写 |

| auto-aof-rewrite-min-size 64mb | 文件体积增长到64mb时执行AOF重写 |

实际工作中不要进行频繁的AOF重写,因为CPU资源和硬盘资源二者之间肯定是CPU资源更加宝贵,所以不应该过多耗费CPU性能去节省硬盘空间。

3.持久化文件损坏修复


Redis服务器启动时如果读取了损坏的持久化文件会导致启动失败,此时为了让Redis服务器能够正常启动,需要对损坏的持久化文件进行修复。这里以AOF文件为例介绍修复操作的步骤。

  • 第一步:备份要修复的appendonly.aof文件

  • 第二步:执行修复程序

/usr/local/redis/bin/redis-check-aof --fix /usr/local/redis/appendonly.aof

  • 第三步:重启Redis

注意:所谓修复持久化文件仅仅是把损坏的部分去掉,而没法把受损的数据找回。

4.扩展阅读:两种持久化机制的取舍


①RDB

[1]优势

适合大规模的数据恢复,速度较快

[2]劣势

会丢失最后一次快照后的所有修改,不能绝对保证数据的高度一致性和完整性。Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑,但上述成立有条件,Linux也有优化手段

②AOF

[1]优势

选择appendfsync always方式运行时理论上能够做到数据完整一致,但此时性能又不好。文件内容具备一定可读性,能够用来分析Redis工作情况。

[2]劣势

持久化相同的数据,文件体积比RDB大,恢复速度比RDB慢。效率在同步写入时低于RDB,不同步写入时与RDB相同。

③RDB和AOF并存

Redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整

RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份)、快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。

④使用建议

如果Redis仅仅作为缓存可以不使用任何持久化方式。

其他应用方式综合考虑性能和完整性、一致性要求。

RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。如果Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值。如果不开启AOF,仅靠Master-Slave Replication 实现高可用性能也不错。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。新浪微博就选用了这种架构。

七、Redis事务控制

=======================================================================

1.Redis事务控制的相关命令


| 命令名 | 作用 |

| — | — |

| MULTI | 表示开始收集命令,后面所有命令都不是马上执行,而是加入到一个队列中。 |

| EXEC | 执行MULTI后面命令队列中的所有命令。 |

| DISCARD | 放弃执行队列中的命令。 |

| WATCH | “观察“、”监控“一个KEY,在当前队列外的其他命令操作这个KEY时,放弃执行自己队列的命令 |

| UNWATCH | 放弃监控一个KEY |

2.命令队列执行失败的两种情况


①加入队列时失败

``` html

127.0.0.1:6379> multi

OK

127.0.0.1:6379> set age 20

QUEUED

127.0.0.1:6379> incr age

QUEUED

127.0.0.1:6379> incr age www

(error) ERR wrong number of arguments for ‘incr’ command

127.0.0.1:6379> exec

(error) EXECABORT Transaction discarded because of previous errors.

```

遇到了入队时即可检测到的错误,整个队列都不会执行。

②执行队列时失败

``` html

127.0.0.1:6379> multi

OK

127.0.0.1:6379> set age 30

QUEUED

127.0.0.1:6379> incrby age 5

QUEUED

127.0.0.1:6379> incrby age 5

QUEUED

127.0.0.1:6379> incrby age ww

QUEUED

127.0.0.1:6379> incrby age 5

QUEUED

127.0.0.1:6379> EXEC

  1. OK

  2. (integer) 35

  3. (integer) 40

  4. (error) ERR value is not an integer or out of range

  5. (integer) 45

127.0.0.1:6379> get age

“45”

```

错误在入队时检测不出来,整个队列执行时有错的命令执行失败,但是其他命令并没有回滚。

③Redis为什么不支持回滚

官方解释如下:

如果你有使用关系式数据库的经验, 那么 “Redis 在事务失败时不进行回滚,而是继续执行余下的命令”这种做法可能会让你觉得有点奇怪。以下是这种做法的优点: 1.Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。 2.因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。 有种观点认为 Redis 处理事务的做法会产生 bug , 然而需要注意的是, 在通常情况下, 回滚并不能解决编程错误带来的问题。 举个例子, 如果你本来想通过 INCR 命令将键的值加上 1 , 却不小心加上了 2 , 又或者对错误类型的键执行了 INCR , 回滚是没有办法处理这些情况的。

3.悲观锁和乐观锁


在使用WATCH命令监控一个KEY后,当前队列中的命令会由于外部命令的执行而放弃,这是乐观锁的体现。

  • 悲观锁

认为当前环境非常容易发生碰撞,所以执行操作前需要把数据锁定,操作完成后释放锁,其他操作才可以继续操作。

  • 乐观锁

认为当前环境不容易发生碰撞,所以执行操作前不锁定数据,万一碰撞真的发生了,那么放弃自己的操作。

八、Redis主从复制机制

=========================================================================

1.读写分离的好处:


  • 性能优化:主服务器专注于写操作,可以用更适合写入数据的模式工作;同样,从服务器专注于读操作,可以用更适合读取数据的模式工作。

  • 强化数据安全,避免单点故障:由于数据同步机制的存在,各个服务器之间数据保持一致,所以其中某个服务器宕机不会导致数据丢失或无法访问。从这个角度说参与主从复制的Redis服务器构成了一个集群

2.搭建步骤


①思路

Redis集群在运行时使用的是同一个可执行文件,只是对应的配置文件不同。

每个配置文件中相同的参数是:

``` html

dir /usr/local/cluster-redis

```

不同的参数有:

| 配置项名称 | 作用 | 取值 |

| — | — | — |

| port | Redis服务器启动后监听的端口号 | 6000

7000

8000 |

| dbfilename | RDB文件存储位置 | dump6000.rdb

dump7000.rdb

dump8000.rdb |

| logfile | 日志文件位置 | /var/logs/redis6000.log

/var/logs/redis7000.log

/var/logs/redis8000.log |

| pidfile | pid文件位置 | /var/run/redis6000.pid

/var/run/redis7000.pid

/var/run/redis8000.pid |

②步骤

  • 第一步:创建/usr/local/cluster-redis目录

  • 第二步:把原始未经修改的redis.conf复制到/usr/local/cluster-redis目录

  • 第三步:把/usr/local/cluster-redis目录下的redis.conf复制为redis6000.conf

  • 第四步:按照既定计划修改redis6000.conf中的相关配置项

  • dir

  • port

  • dbfilename

  • logfile

  • pidfile

  • 第五步:复制redis6000.conf为redis7000.conf

  • 第六步:修改redis7000.conf中的相关配置项

  • port

  • dbfilename

  • logfile

  • pidfile

  • 第七步:复制redis6000.conf为redis8000.conf

  • 第八步:修改redis8000.conf中的相关配置项

  • port

  • dbfilename

  • logfile

  • pidfile

③启动Redis主从复制集群

```html

/usr/local/redis/bin/redis-server /usr/local/cluster-redis/redis6000.conf

/usr/local/redis/bin/redis-server /usr/local/cluster-redis/redis7000.conf

/usr/local/redis/bin/redis-server /usr/local/cluster-redis/redis8000.conf

```

使用redis-cli停止指定服务器的命令格式如下:

/usr/local/bin/redis-cli -h IP地址 -p 端口号 shutdown

3.主从关系


①查看主从关系

``` html

127.0.0.1:6000> info replication

# Replication

role:master

connected_slaves:0

```

刚刚启动的集群服务器中每一个节点服务器都认为自己是主服务器。需要建立主从关系。

②设定主从关系

在从机上指定主机位置即可

``` html

SLAVEOF 127.0.0.1 6000

```

③取消主从关系

在从机上执行命令

总结:心得体会

既然选择这个行业,选择了做一个程序员,也就明白只有不断学习,积累实战经验才有资格往上走,拿高薪,为自己,为父母,为以后的家能有一定的经济保障。

学习时间都是自己挤出来的,短时间或许很难看到效果,一旦坚持下来了,必然会有所改变。不如好好想想自己为什么想进入这个行业,给自己内心一个答案。

面试大厂,最重要的就是夯实的基础,不然面试官随便一问你就凉了;其次会问一些技术原理,还会看你对知识掌握的广度,最重要的还是你的思路,这是面试官比较看重的。

最后,上面这些大厂面试真题都是非常好的学习资料,通过这些面试真题能够看看自己对技术知识掌握的大概情况,从而能够给自己定一个学习方向。包括上面分享到的学习指南,你都可以从学习指南里理顺学习路线,避免低效学习。

大厂Java架构核心笔记(适合中高级程序员阅读):

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

③启动Redis主从复制集群

```html

/usr/local/redis/bin/redis-server /usr/local/cluster-redis/redis6000.conf

/usr/local/redis/bin/redis-server /usr/local/cluster-redis/redis7000.conf

/usr/local/redis/bin/redis-server /usr/local/cluster-redis/redis8000.conf

```

使用redis-cli停止指定服务器的命令格式如下:

/usr/local/bin/redis-cli -h IP地址 -p 端口号 shutdown

3.主从关系


①查看主从关系

``` html

127.0.0.1:6000> info replication

# Replication

role:master

connected_slaves:0

```

刚刚启动的集群服务器中每一个节点服务器都认为自己是主服务器。需要建立主从关系。

②设定主从关系

在从机上指定主机位置即可

``` html

SLAVEOF 127.0.0.1 6000

```

③取消主从关系

在从机上执行命令

总结:心得体会

既然选择这个行业,选择了做一个程序员,也就明白只有不断学习,积累实战经验才有资格往上走,拿高薪,为自己,为父母,为以后的家能有一定的经济保障。

学习时间都是自己挤出来的,短时间或许很难看到效果,一旦坚持下来了,必然会有所改变。不如好好想想自己为什么想进入这个行业,给自己内心一个答案。

面试大厂,最重要的就是夯实的基础,不然面试官随便一问你就凉了;其次会问一些技术原理,还会看你对知识掌握的广度,最重要的还是你的思路,这是面试官比较看重的。

最后,上面这些大厂面试真题都是非常好的学习资料,通过这些面试真题能够看看自己对技术知识掌握的大概情况,从而能够给自己定一个学习方向。包括上面分享到的学习指南,你都可以从学习指南里理顺学习路线,避免低效学习。

大厂Java架构核心笔记(适合中高级程序员阅读):

[外链图片转存中…(img-g7c0nYXL-1714741725215)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值