ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Redis学习笔记——快速入门篇

2021-05-24 11:01:38  阅读:175  来源: 互联网

标签:127.0 6379 0.1 redis Redis 笔记 入门篇 key integer


redis快速入门

1.redis概述

Redis:REmote DIctionary Server(远程字典服务器)

是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(Key/Value)分布式内存数据库,基于内存运行,并支持持久化的NoSQL数据库,是当前最热门的NoSQL数据库之一,也被人们称为数据结构服务器。

Redis与其他key-value缓存产品有以下三个特点

  • Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的 key-value 类型的数据,同时还提供list、set、zset、hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

2.redis常识问题

redis默认16个数据库,类似数组下标从零开始,初始默认使用零号库。

在redis的配置文件redis.conf中,可以查看数据库的默认配置!!!

Select命令切换数据库

select 7 #切换到第七个数据库

Dbsize查看当前数据库的key的数量

DBSIZE

Flushdb:清空当前库
Flushall:清空全部的库

关于Key的一些操作

# 查看所有的key
keys * 
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set name haha
OK
127.0.0.1:6379> keys *
1) "name"
# exists key 的名字,判断某个key是否存在
127.0.0.1:6379> EXISTS name
(integer) 1
127.0.0.1:6379> EXISTS name1
(integer) 0
# 移除当前库中的key
move key db ---> 当前库就没有了,被移除了
127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> keys *
(empty list or set)
# 为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。
expire key 秒钟:
# ttl key 查看还有多少秒过期,-1 表示永不过期,-2 表示已过期
127.0.0.1:6379> set name haha
OK

常用命令说明:
127.0.0.1:6379> EXPIRE name 10
(integer) 1
127.0.0.1:6379> ttl name
(integer) 4
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) 2
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> keys *
(empty list or set)
# 查看你的key是什么类型
type key
127.0.0.1:6379> set name haha
OK
127.0.0.1:6379> get name
"haha"
127.0.0.1:6379> type name
string

更多redis命令

为什么redis是单线程

redis 6 之前的版本是单进程、单线程的,6版本之后支持多线程!!!

redis很快,是因为redis是基于内存的操作,CPU不是redis的瓶颈,redis
的瓶颈最有可能是机器内存的大小或者网络带宽!!!

先说两个误区:一、高性能的服务器不一定都是多进程、多线程的;二、多线程不一定都不比单线程快,比如单核机器。

在我们通常的认知中,高性能都是通过多进程、多线程实现的。比如Nginx是多进程单线程的,Memcached是单进程多线程的。

在计算机的世界中,CPU的速度是远大于内存的速度的,同时内存的速度也是远大于硬盘的速度。redis的操作都是基于内存的,绝大部分请求是纯粹的内存操作,非常迅速,使用单线程可以省去多线程时CPU上下文会切换的时间,也不用去考虑各种锁的问题,不存在加锁释放锁操作,没有死锁问题导致的性能消耗。对于内存系统来说,多次读写都是在一个CPU上,没有上下文切换效率就是最高的!既然单线程容易实现,而且 CPU 不会成为瓶颈,那就顺理成章的采用单线程的方案了(毕竟采用多线程会有很多麻烦)。

3.五大数据类型

redis的用处

  • 作为数据库存储数据
  • 缓存
  • 消息中间件MQ

五种数据结构

  • String:字符串类型
  • List:列表类型
  • Set:无序集合类型
  • ZSet:有序集合类型
  • Hash:哈希表类型

本篇笔记仅对redis的基本操作进行总结,关于底层的实现,详见后续学习笔记!!!

3.1String类型

单值单value

常用操作、增删查

127.0.0.1:6379> set hello redis
OK
127.0.0.1:6379> get hello
"redis"
127.0.0.1:6379> del hello
(integer) 1
127.0.0.1:6379> get hello
(nil)

append、strlen

# hello不存在
127.0.0.1:6379> exists hello
(integer) 0
# # 对不存在的key进行APPEND,等同于 SET 语句
127.0.0.1:6379> append hello redis2
(integer) 6
127.0.0.1:6379> get hello
"redis2"
# 对已存在的key进行APPEND,直接在string后加内容
127.0.0.1:6379> append hello redis3
(integer) 12
127.0.0.1:6379> get hello
"redis2redis3"
127.0.0.1:6379> strlen hello
(integer) 12

incr、decr 加1、减1
incrby、decrby 加上、减去指定的增量值

String类型的value还可以存储数字

127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> decr views
(integer) 1
127.0.0.1:6379> get views
"1"

3.2列表list

lpush、rpush 添加list数据

#lpush:将一个或多个值插入到列表头部。(左)
#rpush:将一个或多个值插入到列表尾部。(右)
lpush list-key item
rpush list-key item

lrange、lindex 获取数据

#lrange:返回列表中指定区间内的元素,区间以偏移量START和STOP指定
lrange list-key start stop
#lindex:返回index位置的元素
lindex list-key 

lpop、rpop 删除list中的数据

#lpop 命令用于移除并返回列表的第一个元素。当列表 key 不存在时,返回nil 。
lpop list-key
#rpop 移除列表的最后一个元素,返回值为移除的元素。
rpop list-key

应用场景:
Redis list的应用场景非常多,也是Redis最重要的数据结构之一。我们可以轻松地实现最新消息排行等功能。Lists的另一个应用就是消息队列,可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出进行执行。

3.3无序集合Set

单值多value

sadd 添加元素

# sadd 将一个或多个成员元素加入到集合中,不能重复
127.0.0.1:6379> sadd set a,b
(integer) 1
127.0.0.1:6379> sadd set c
(integer) 1
127.0.0.1:6379> sadd set d,eee,ff
(integer) 1

smembers 获取数据

# smembers 返回集合中的所有的成员。
127.0.0.1:6379> smembers set
1) "d,eee,ff"
2) "a,b"
3) "c"

sismember 判断成员元素是否是集合的成员。

127.0.0.1:6379> smembers set
1) "d,eee,ff"
2) "a,b"
3) "c"
127.0.0.1:6379> sismember set c
(integer) 1
127.0.0.1:6379> sismember set a
(integer) 0

应用场景:
Redis为集合提供了求交集、并集、差集等操作,故可以用来求共同好友等操作。

3.4有序集合Zset

zadd 添加数据

# 将一个或多个成员元素及其分数值加入到有序集当中。
127.0.0.1:6379> zadd zset 3 haha
(integer) 1
127.0.0.1:6379> zadd zset 1 ming 2 hong
(integer) 2

zrange 获取数据

# 返回有序集中,指定区间内的成员
127.0.0.1:6379> zrange zset 0 1
1) "ming"
2) "hong"
127.0.0.1:6379> zrange zset 0 -1
1) "ming"
2) "hong"
3) "haha"

zrangebyscore 返回分数score之间的数据

# 返回有序集合中指定分数区间的成员列表。有序集成员按分数值递增(从小到大)
次序排列。
127.0.0.1:6379> zrangebyscore zset 0 1
1) "ming"
127.0.0.1:6379> zrangebyscore zset 1 3
1) "ming"
2) "hong"
3) "haha"

zrem 删除数据

# 移除有序集中的一个或多个成员
127.0.0.1:6379> zrem zset hong
(integer) 1

应用场景
以某个条件为权重,比如按顶的次数排序,ZREVRANGE命令可以用来按照得分来获取前100名的用户,ZRANK可以用来获取用户排名,非常直接而且操作容易。Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。

3.5哈希表Hash

kv模式不变,但V是一个键值对

hset 添加元素

# hset key field value
127.0.0.1:6379> hset hash hash1 value1
(integer) 1
127.0.0.1:6379> hset hash hash1 value2
(integer) 0
127.0.0.1:6379> hset hash hash2 value2 hash3 value3
(integer) 2

hget 、hgetall 获取元素

# hget key field
127.0.0.1:6379> hget hash hash1
"value1"
# hgetall key
127.0.0.1:6379> hgetall hash
1) "hash1"
2) "value2"
3) "hash2"
4) "value2"
5) "hash3"
6) "value3"

hmset、hmget 对多个field-value对进行操作

# 同时将多个field-value对设置到哈希表中。会覆盖哈希表中已存在的字段。
127.0.0.1:6379> hmset mhash hash1 value1 hash2 value2
OK
127.0.0.1:6379> hmget mhash hash1 hash2
1) "value1"
2) "value2"

hdel 删除数据

# 用于删除哈希表key中的一个或多个指定字段
127.0.0.1:6379> hdel hash hash1 hash2
(integer) 2
127.0.0.1:6379> hgetall hash
1) "hash3"
2) "value3"

应用场景
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。存储部分变更的数据,如用户信息等。

4.读懂redis的配置文件redis.conf

配置文件开头就说了redis-server的使用

在这里插入图片描述
Redis启动的时候,通过配置文件来启动
命令:redis-server /usr/local/bin/myredis/redis.conf(配置文件的路径)

单位 Units

在这里插入图片描述

  • 配置大小单位,开头定义了一些基本的度量单位,只支持bytes,不支持bit
  • 对大小写不敏感

includes 可以包含其他配置文件

在这里插入图片描述

network

bind 127.0.0.1 # 绑定的ip
protected-mode yes # 保护模式,是否受保护,默认开启
port 6379 # 默认端口

general 通用配置

# 默认情况下,Redis不作为守护进程运行。需要开启的话,改为 yes
daemonize yes 
# 可通过upstart和systemd管理Redis守护进程
supervised no 
# 以后台进程方式运行redis,则需要指定pid 文件
pidfile /var/run/redis_6379.pid 
# 日志级别。可选项有:
# debug(记录大量日志信息,适用于开发、测试阶段);
# verbose(较多日志信息);
# notice(适量日志信息,使用于生产环境);
# warning(仅有部分重要、关键信息才会被记录)。
loglevel notice
# 日志文件的位置,当指定为空字符串时,为标准输出
logfile "" 
# 设置数据库的数目。默认的数据库是DB 0
databases 16 
# 是否总是显示logo,开启redis服务那个logo
always-show-logo yes 

快照

什么是快照呢?快照是实现持久化的一种方法。快照,可以理解为拍照一样,把整个内存数据映射到硬盘中,保存一份到硬盘,因此恢复数据起来比较快,把数据映射回去即可!!!

# 900秒(15分钟)内至少1个key值改变(则进行数据库保存--持久化)
save 900 1
# 300秒(5分钟)内至少10个key值改变(则进行数据库保存--持久化)
save 300 10
# 60秒(1分钟)内至少10000个key值改变(则进行数据库保存--持久化)
save 60 10000
stop-writes-on-bgsave-error yes # 持久化出现错误后,是否依然进行继续进行工作
rdbcompression yes # 使用压缩rdb文件 yes:压缩,但是需要一些cpu的消耗。no:不压
缩,需要更多的磁盘空间
rdbchecksum yes # 是否校验rdb文件,更有利于文件的容错性,但是在保存rdb文件的时候,会有大概10%的性能损耗
dbfilename dump.rdb # dbfilenamerdb文件名称
dir ./ # dir 数据目录,数据库的写入会在这个目录。rdb、aof文件也会写在这个目录

注:rdb文件是持久化的文件(快照文件),它保存了redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份和灾难恢复。

security 安全

访问密码的查看,设置和取消

# 启动redis
# 连接客户端
# 获得和设置密码
config get requirepass
config set requirepass "123456"
#测试ping,发现需要验证
127.0.0.1:6379> ping
NOAUTH Authentication required.
# 验证
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> ping
PONG

客户端的一些限制

maxclients 10000 # 设置能连上redis的最大客户端连接数量
maxmemory <bytes> # redis配置的最大内存容量
maxmemory-policy noeviction # maxmemory-policy 内存达到上限的处理策略

6种处理策略

  • volatile-lru:利用LRU算法移除设置过期时间的key。
  • volatile-random:随机移除设置过期时间的key。
  • volatile-ttl:移除即将过期的key,根据最近过期时间来删除(辅以TTL)
  • allkeys-lru:利用LRU算法移除任何key。
  • allkeys-random:随机移除任何key。
  • noeviction:不移除任何key,只是返回一个写错误

appendonly 模式

默认使用rdb持久化方式,不开启aof模式

appendonly no # 是否以append only模式作为持久化方式
appendfilename "appendonly.aof" # appendfilename AOF 文件名称
appendfsync everysec # appendfsync aof持久化策略的配置

AOF持久化配置策略

  • no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快。
  • always表示每次写入都执行fsync,以保证数据同步到磁盘。
  • everysec表示每秒执行一次fsync,可能会导致丢失这1s数据。

5.redis的事务

5.1理论

redis单条命令是保证原子性的,但是事务不保证原子性!!!

Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
总结说:redis事务就是一次性顺序性排他性的执行一个队列中的一系列命令。

Redis事务没有隔离级别的概念:

批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行!

Redis不保证原子性:

Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。

Redis事务的三个阶段:

  • 开始事务multi
  • 命令入队
  • 执行事务exec

Redis事务相关命令如下:

watch key1 key2 ... #监视一个或多个key,如果在事务执行之前,被监视的key被其他命令改动,则事务被打断 ( 类似乐观锁 )
multi # 标记一个事务块的开始( queued )
exec # 执行所有事务块的命令 ( 一旦执行exec后,之前加的监控锁都会被取消掉 )
discard # 取消事务,放弃事务块中的所有命令
unwatch # 取消watch对所有key的监控

Watch命令详解:

watch监控指令类似于乐观锁,在事务提交时,如果watch监控的多个KEY中任何KEY的值已经被其他客户端更改,则使用EXEC执行事务时,事务队列将不会被执行,同时返回Nullmulti-bulk应答以通知调用者事务执行失败。

测试watch命令的使用!!!

转账,A转给B100元,A有1000,B有0

正常执行成功!

127.0.0.1:6379> set A 1000
OK
127.0.0.1:6379> set B 0
OK
127.0.0.1:6379> watch A
OK
#事务正常结束,数据期间没有发生变动,这个时候就正常执行成功!!!
127.0.0.1:6379> multi  
OK
127.0.0.1:6379> decrby A 100
QUEUED
127.0.0.1:6379> incrby B 100
QUEUED
127.0.0.1:6379> exec
1) (integer) 900
2) (integer) 100

场景:小明去给账户充钱(A),充到1000;小红用账户的钱(A)给小李转账(B)100;俩人同时进行!!!

127.0.0.1:6379> get A
"900"
127.0.0.1:6379> set A 1000
OK
127.0.0.1:6379> watch A # 加锁
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby A 100
QUEUED
127.0.0.1:6379> incrby B 100
QUEUED
127.0.0.1:6379> exec
(nil)

在小红转账期间,加上watch乐观锁,小明给账户充钱了,小红转账失败!!!

:一但执行 EXEC 开启事务的执行后,无论事务使用执行成功, WARCH 对变量的监控都将被取消。
故当事务执行失败后,需重新执行WATCH命令对变量进行监控,并开启新的事务进行操作。

标签:127.0,6379,0.1,redis,Redis,笔记,入门篇,key,integer
来源: https://blog.csdn.net/qq_41343930/article/details/117113489

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有