Redis===》数据类型之列表有序无序,常用命令,RDBAOFRDB+AOF
Posted FikL-09-19
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis===》数据类型之列表有序无序,常用命令,RDBAOFRDB+AOF相关的知识,希望对你有一定的参考价值。
Redis===》数据类型之列表、有序、无序,常用命令,RDB、AOF、RDB+AOF
一、nosql介绍
1.缓存的统称:nosql (非关系型数据库)
1、nodql特点
代表着不仅仅是sql
没有声明性查询语言
没有预定义的模式
键-值对存储,列存储,文档存储,图形数据库
最终一致性,而非ACID属性
2、为什么使用nosql
随着互联网飞速发展,数据访问量和存储量高速扩大,传统的架构APP访问DAL层,DAL层在查询直接通过关系数据库(比如mysql数据库)获取数据返回给用户已然出现了性能问题。为了解决这一问题,需要对数据库和数据表水平拆分和垂直拆分。
数据库拆分之后就会出现多个数据库,多个数据库又分别部署在不同的服务器,这时就需要对数据库进行集群,为了保证多台机器的缓存一致、可用性和分区容错性,分布式缓存(redis)的诞生正好解决了这个痛点。
分布式缓存为多个web服务器提供一个共享的高性能缓存服务。
2.企业中常用的缓存数据库比较
1、Memcached
Memcached是一个自由开源的,高性能,分布式内存对象缓存系统
Memcached是以 LiveJournal 旗下 Danga Interactive 公司的 Brad Fitzpatric 为首开发的一款软件。现在已成为 mixi、hatena、Facebook、Vox、LiveJournal 等众多服务中提高 Web 应用扩展性的重要因素。
Memcached 是一种基于内存的 key-value 存储,用来存储小块的任意数据(字符串、对象)。这些数据可以 是数据库调用、API 调用或者是页面渲染的结果。
Memcached 简洁而强大。它的简洁设计便于快速开发,减轻开发难度,解决了大数据量缓存的很多问题。 它的 API 兼容大部分流行的开发语言。 本质上,它是一个简洁的 key-value存储系统
一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态 Web 应用的速度、提高 可扩展性。
2、Memcached优缺点
优点:高性能读写、单一数据类型、支持客户端分布式集群、一致性hash多和结构、多线程读写性能高。
缺点:无持久化、节点故障可能出现缓存穿透、分布式需要客户端实现、跨机房数据同步困难、架构扩容复杂度高
3、Redis
REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统。
Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、 Key-Value 数据库,并提供多种语言的 API。
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型
4、Redis优缺点
优点:高性能读写、多数据类型支持、数据持久化、高可用架构、支持自定义虚拟内存、支持分布式分片集群、单线程读写性能极高
缺点:不支持多线程读写,相比Memcached会慢
5、Tair
Tair 是由淘宝网自主开发的 Key/Value 结构数据存储系统,在淘宝网有着大规模的应用。您在登录淘宝、查 看商品详情页面或者在淘江湖和好友“捣浆糊”的时候,都在直接或间接地和 Tair 交互
Tair 是一个 Key/Value 结构数据的解决方案,它默认支持基于内存和文件的两种存储方式,分别和我们通常 所说的缓存和持久化存储对应
Tair 除了普通 Key/Value 系统提供的功能,比如 get、put、delete 以及批量接口外,还有一些附加的实用功能, 使得其有更广的适用场景
6、Tair优缺点
优点:高性能读写、支持三种存储引擎(ddb、rdb、ldb)、支持高可用、支持分布式分片集群、支撑了几乎所有淘宝业务的缓存
缺点:单机情况下,读写性能较其他两种产品较慢
7、总结
Memcached:多核的缓存服务,更加适合于多用户并发访问次数(访问次数较少的应用场景)
Redis:单核缓存服务,在单节点的情况下,更加适合少量用户,多次访问的应用场景。
二、企业级缓存中间件Redis
1.软件特性
透明性:分布式系统对用户来说是透明的,一个分布式系统在用户面前的表现就像一个传统的单处理机分时 系统,可让用户不必了解内部结构就可以使用。
扩展性:分布式系统的最大特点就是可扩展性,他可以根据需求的增加而扩展,可以通过横向扩展使集群的 整体性能得到线性提升,也可以通过纵向扩展单台服务器的性能使服务器集群的性能得到提升
可靠性:分布式系统不允许单点失效的问题存在,它的基本思想是:如果一台服务器坏了,其他服务器接替 它的工作,具有持续服务的特性。
高性能:高性能是人们设计分布式系统的一个初衷,如果建立了一个透明,灵活,可靠的分布式系统,但他 运行起来像蜗牛一样慢,那这个系统就是失败的
2.Redis的常用功能
高速读写:Redis 在运行时,将数据放在内存当中,利用内存的高性能的特性提高自己的服务性能
数据类型丰富:Redis 具有丰富的数据类型,可以适用于各种场景
支持持久化:因为 Redis 的数据是放在内存当中的,当 Redis 关机或者内存失效时,数据随即丢失,不可找 回,为了避免 Redis 重启时发生类似于雪崩事件,所以 Redis 官方增加了一个数据持久化的功能。
多种内存分配及回收策略:Redis 可以通过 maxmemory 参数来限制最大可用内存,主要为了避免 Redis 内 存超过操作系统内存,从而导致服务器响应变慢甚至死机的情况。而回收策略主要是删除过期的 key 以及内 存达到 maxmemory
支持事物:Redis 也支持类似于 MySQL 数据库那样的事务
消息队列、消息订阅: Redis 的列表类型键可以用来实现队列,并且支持阻塞式读取,可以很容易的实现 一个高性能的优先队列。同时在更高层面上,Redis 还支持"发布/订阅"的消息模式,可以基于此构建一个聊 天系统
支持高可用:Redis 支持两种高可用集群方式
扩展 --面试题
redi出现问题的两种现象:
#1.缓存雪崩:Redis缓存层由于某种原因宕机后,所有的请求会涌向数据库存储层,短时间内的高并发请求可能会导致存储层挂机,称之为“Redis雪崩”。
规避方案:1.服务器启动时,提前写入
2.规范key的命名,通过中间件拦截
3.对某些高频访问的key,设置合理的TTL或永不过期
#2.缓存击穿:在Redis获取某一key时, 由于key不存在, 而必须向数据库发起一次请求的行为, 称为“Redis击穿”。
规避方案:1.使用redis集群
2.限流
3.redis安装
1、编译安装
#1.解压
[root@docker ~]# wget https://download.redis.io/releases/redis-6.0.9.tar.gz
[root@docker ~]# tar -xf redis-6.0.9.tar.gz -C /usr/local
[root@docker ~]# cd /usr/local/redis-6.0.9/
#2.编译
在linux中编译软件需要安装gcc gcc-c++ make 等如软件。
[root@docker redis-6.0.9]# yum -y install centos-release-scl
[root@docker redis-6.0.9]# yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
[root@docker redis-6.0.9]# scl enable devtoolset-9
[root@docker redis-6.0.9]# make -j #多核编译
#3.安装
[root@docker redis-6.0.9]# make PREFIX=/usr/local/redis install #指定目录安装
#4.将配置文件移动到指定目录
[root@docker redis]# mkdir conf
[root@docker redis]# mv ../redis-6.0.9/redis.conf conf/
[root@docker redis]# ll
总用量 0
drwxr-xr-x 2 root root 134 4月 30 20:35 bin
drwxr-xr-x 2 root root 24 4月 30 20:38 conf
[root@docker redis]# ll conf/
总用量 84
-rw-rw-r-- 1 root root 84841 10月 27 2020 redis.conf
#5.启动
[root@docker redis]# ./bin/redis-server ./conf/redis.conf #指定配置文件启动、
#6.验证启动
[root@docker ~]# cd /usr/local/redis
[root@docker redis]# ./bin/redis-cli
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379>
2、容器安装
kind: Deployment
apiVersion: apps/v1
metadata:
name: redis-deployment
spec:
selector:
matchLabels:
app: redis
deploy: redis
template:
metadata:
labels:
app: redis
deploy: redis
spec:
containers:
- name: redis
image: redis:6.0.9
---
kind: Service
apiVersion: v1
metadata:
name: redis-deployment-svc
spec:
ports:
- port: 6379
targetPort: 6379
name: redis
protocol: TCP
selector:
app: redis
deploy: redis
type: NodePort
3.使用systemctl管理redis
#1.注册服务
cat > /usr/lib/systemd/system/redis.service << EOF
[Unit]
Description=Redis
After=network.target
[Service]
Type=forking
PIDFile=/var/run/redis_6379.pid
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
#2.修改配置文件
[root@docker conf]# vim /usr/local/redis/conf/redis.conf
daemonize yes #将no改为yes
#3.使用systemctl启动redis
[root@docker conf]# systemctl start redis
4.添加环境变量
#1.修改配置文件内容
[root@docker conf]# vim /etc/profile
在最后添加内容
export REDIS_HOME=/usr/local/redis
PATH=$PATH:$REDIS_HOME/bin
[root@docker conf]# source /etc/profile #重新加载环境变量
#2.测试
[root@docker ~]# redis-cli
127.0.0.1:6379>
5、设置密码
#1.修改配置文件
[root@docker conf]# vim /usr/local/redis/conf/redis.conf
requirepass 123
#2.重启
[root@docker ~]# systemctl restart redis.service
#进入以后提示无权限 需要密码
[root@docker ~]# redis-cli
127.0.0.1:6379> set a b
(error) NOAUTH Authentication required.
#1.使用密码进入
[root@docker ~]# redis-cli -a 123
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379>
#2.进入后使用密码
[root@docker ~]# redis-cli
127.0.0.1:6379> AUTH 123
OK
6.解决中文乱码问题
[root@docker ~]# redis-cli
127.0.0.1:6379> set name 一夜暴富
OK
127.0.0.1:6379> get name
"\\xe4\\xb8\\x80\\xe5\\xa4\\x9c\\xe6\\x9a\\xb4\\xe5\\xaf\\x8c" #获取乱码
[root@docker ~]# redis-cli --raw
127.0.0.1:6379> auth 123
OK
127.0.0.1:6379> get name
明明
三、redis数据结构
1.字符串
#1.添加
127.0.0.1:6379> set name 明明
OK
#2.获取
127.0.0.1:6379> get name
一夜暴富
#3.修改
127.0.0.1:6379> set name yeyeyeyeye
OK
127.0.0.1:6379> get name
yeyeyeyeye
#4.删除
127.0.0.1:6379> del name
1
127.0.0.1:6379> get name
#5.判断一个key是否存在
127.0.0.1:6379> exists name
0
127.0.0.1:6379> set name lll
OK
127.0.0.1:6379> exists name
1
#6.过期时间
127.0.0.1:6379> TTL name #查看过期时间
-1 #永不过期
127.0.0.1:6379> TTL name
-2 # 已经过期了
127.0.0.1:6379> TTL name
5 # 剩下5秒钟就过期了
#7.设置一个以毫秒为单位的过期时间
127.0.0.1:6379> set name lll px 1000
OK
#8.设置一个以秒为单位的过期时间
127.0.0.1:6379> set name lll ex 10
OK
#9.合并set和ex
127.0.0.1:6379> SETEX name 10 abc #key+秒数+value
#10.合并set和px
127.0.0.1:6379> PSETEX name 10000 dbc #key+秒数+value
#11.判断一个key不存在则创建,存在则忽略
(NX:当key不存在时创建,已存在则忽略)
127.0.0.1:6379> set name lll nx
OK
127.0.0.1:6379> get name
lll
127.0.0.1:6379> set name qqq nx #存在则忽略
127.0.0.1:6379> get name
lll
#12.合并set和nx
127.0.0.1:6379> SETNX name yangge
0
127.0.0.1:6379> get name
yangge
127.0.0.1:6379> SETNX name chenyang
0
127.0.0.1:6379> get name
yangge
#13.判断一个key存在则更新,不存在则忽略
(XX:当key存在则更新,不存在则忽略)
127.0.0.1:6379> get name
lll
127.0.0.1:6379> set name qqq xx
OK
127.0.0.1:6379> get name
qqq
#14.设置多个值
127.0.0.1:6379> MSET b c d e f g
OK
127.0.0.1:6379> KEYS *
f
b
a
d
name
127.0.0.1:6379> get b
c
127.0.0.1:6379> get d
e
127.0.0.1:6379> get f
g
127.0.0.1:6379>
#15.删除多个值
127.0.0.1:6379> KEYS *
1) "a"
2) "name"
3) "d"
127.0.0.1:6379> del a d
(integer) 2
127.0.0.1:6379> KEYS *
1) "name"
#16.GETSET
(相当于get+set:先执行get命令,返回get结果,然后将key更新为新的value,下次再get的时候查到的就是新得value)
127.0.0.1:6379> GETSET name lalala
"qqq"
127.0.0.1:6379> get name
"lalala"
#17.按照下标去更新
127.0.0.1:6379> SETRANGE name 2 ,,,
(integer) 6
127.0.0.1:6379> GET name #在第二位数后添加指定内容
"la,,,a"
#18.获取多个key值
127.0.0.1:6379> MGET get name
1) (nil)
2) "la,,,a"
#19.截取
127.0.0.1:6379> get name #截取name值的2-4位
"la,,,a"
127.0.0.1:6379> getrange name 2 4
",,,"
#20.计数
(Redis当中的计数器是具有原子性的)
127.0.0.1:6379> INCR num # 递增
1
127.0.0.1:6379> DECR num # 递减
0
#21.指定长度递增
127.0.0.1:6379> INCRby num 21
236
#22.指定长度递减
127.0.0.1:6379> decrby num 21
26
#23.追加
127.0.0.1:6379> get name
"la,,,a"
127.0.0.1:6379> append name --
(integer) 8
127.0.0.1:6379> get name
"la,,,a--"
2.哈希
#怎样用一个key存一个人的信息呢?
#1.写入数据
127.0.0.1:6379> hset people name yiyebaofu sex man add tianjin
(integer) 3
#2.获取数据
127.0.0.1:6379> hget people name
"yiyebaofu"
127.0.0.1:6379> hget people add
"tianjin"
#4.修改数据
127.0.0.1:6379> hset people name lalala
(integer) 0
127.0.0.1:6379> hget people name
"lalala"
#5.删除数据
127.0.0.1:6379> hdel people name
(integer) 1
127.0.0.1:6379> hget people name
(nil)
#6.删除所有数据
127.0.0.1:6379> del people
(integer) 1
127.0.0.1:6379> hget people name
(nil)
127.0.0.1:6379> hget people add
(nil)
#7.获取多个值
127.0.0.1:6379> hset peopel name yeyeye sex man add tianjian
(integer) 3
127.0.0.1:6379> hmget peopel name add sex
1) "yeyeye"
2) "tianjian"
3) "man"
#8.获取所有的key和value
127.0.0.1:6379> hgetall peopel
1) "name"
2) "yeyeye"
3) "sex"
4) "man"
5) "add"
6) "tianjian"
#9.获取所有的key
127.0.0.1:6379> hkeys peopel
1) "name"
2) "sex"
3) "add"
#10.获取所有的value
127.0.0.1:6379> hvals peopel
1) "yeyeye"
2) "man"
3) "tianjian"
#11.计数(增加)
127.0.0.1:6379> hincrby peopel id 1
(integer) 1
127.0.0.1:6379> hincrby peopel id 1
(integer) 2
127.0.0.1:6379> hincrby peopel id 1
(integer) 3
127.0.0.1:6379> hget peopel id
"3"
#12.计数(递减)
127.0.0.1:6379> hget peopel id
"3"
127.0.0.1:6379> hincrby peopel id -1
(integer) 2
127.0.0.1:6379> hincrby peopel id -1
(integer) 1
127.0.0.1:6379> hget peopel id
"1"
#13.计数(小数点)
127.0.0.1:6379> HINCRBYFLOAT peopel num 1.1
"1.1"
127.0.0.1:6379> HINCRBYFLOAT peopel num 1.1
"2.2"
127.0.0.1:6379> HINCRBYFLOAT peopel num 1.1
"3.3"
127.0.0.1:6379> HINCRBYFLOAT peopel num 1.1
"4.4"
===========================================
127.0.0.1:6379> HINCRBYFLOAT people num 10.9
134.09
127.0.0.1:6379> HINCRBYFLOAT people num 10.9
144.98999999999999999 # 精度不够
#14.获取长度
127.0.0.1:6379> hlen peopel
(integer) 5
#15.获取某个字段的长度
127.0.0.1:6379> hstrlen peopel num
(integer) 3
#16.设置过期时间
17.0.0.1:6379> expire peopel 111
(integer) 1
以上是关于Redis===》数据类型之列表有序无序,常用命令,RDBAOFRDB+AOF的主要内容,如果未能解决你的问题,请参考以下文章