一、redis基础
1.1 关系型数据库和NoSQL数据库
数据库主要分为两大类:关系型数据库与 NoSQL 数据库。
关系型数据库,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库中的数据。主流的 MySQL、Oracle、MS SQL Server 和 DB2 都属于这类传统数据库。
NoSQL 数据库,全称为 Not Only SQL,意思就是适用关系型数据库的时候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可,可以考虑使用更加合适的数据存储。主要分为临时性键值存储(memcached、Redis)、永久性键值存储(ROMA、Redis)、面向文档的数据库(MongoDB、CouchDB)、面向列的数据库(Cassandra、HBase),每种 NoSQL 都有其特有的使用场景及优点。
Oracle,mysql等传统的关系型数据库非常成熟并且已大规模商用,为什么还要用NoSQL数据库呢?
主要是因为由于随着互联网的发展,数据量越来越大,对性能要求越来越高,传统数据库存在着先天性的缺陷,即单机(单库)性能瓶颈,并且扩展困难。这样既有单机单库瓶颈,却又扩展困难,自然无法满足日益增长的海量数据存储及其性能要求,所以才会出现了各种不同的 NoSQL 产品,NoSQL 根本性的优势在于在云计算时代,简单、易于大规模分布式扩展,并且读写性能非常高。
关系型数据库 | NoSQL数据库 | |
特点 | 数据关系模型基于关系模型,结构化存储,完整性约束 基于二维表及其之间的联系,需要连接、并、交、差、除等数据操作 采用结构化的查询语言(SQL)做数据读写 操作需要数据的一致性,需要事务甚至是强一致性 | 非结构化的存储 基于多维关系模型 具有特有的使用场景 |
优点 | 保持数据的一致性(事务处理) 可以进行join等复杂查询 通用化,技术成熟 | 高并发,大数据下读写能力较强 基本支持分布式,易于扩展,可伸缩 简单,若结构化存储 |
缺点 | 数据读写必须经过sql解析,大量数据、高并发下读写性能不足 对数据做读写,或修改数据结构时需要加锁,影响并发操作 无法适应非结构化存储 | join等复杂操作能力较弱 事务支持较弱 通用性差 无完整约束复杂业务场景支持较差 |
1.2 Redis简介
Redis (Remote Dictionary Server)在2009年发布,开发者Salvatore Sanfilippo是意大利开发者,他本想为自己的公司开发一个用于替换MySQL的产品Redis,但是没有想到他把Redis开源后大受欢迎,短短几年,Redis就有了很大的用户群体,目前国内外使用的公司众多,比如:阿里,百度,新浪微博,知乎网,GitHub,Twitter 等。
Redis是一个开源的、遵循BSD协议的、基于内存的而且目前比较流行的键值数据库(key-value database),是一个非关系型数据库,redis 提供将内存通过网络远程共享的一种服务,提供类似功能的还有memcached,但相比memcached,redis还提供了易扩展、高性能、具备数据持久性等功能。
Redis 在高并发、低延迟环境要求比较高的环境使用量非常广泛。
1.3 Redis特性
速度快、单线程、持久化、支持多种数据结构、支持多种编程语言、功能丰富、简单、主从复制、支持高可用和分布式
1.4 单线程
Redis 6.0版本前一直是单线程方式处理用户的请求。
单线程快:存内存、非阻塞、避免线程切换和竞态消耗
Redis为什么这么快:
1.Redis是一款纯内存结构,避免了磁盘I/O等耗时操作
2.Redis命令处理的核心模块为单线程,减少了锁竞争,以及频繁创建线程和销毁线程的代价,减少了线程上下文切换的消耗。
3.采用了I/O多路复用机制,大大提高了并发效率
注意:
1.一次只运行一条命令
2.拒绝长(慢)命令:keys, flushall, flushdb, slow lua script, mutil/exec, operate big value(collection)
3.其实不是单线程: 早期版本是单进程单线程,3版本后实际还有其它的线程, 实现特定功能,如: fysnc file descriptor,close file descriptor
1.5 Redis典型应用场景
1.Session 共享:常见于web集群中的Tomcat或者PHP中多web服务器session共享
2.缓存:数据查询、电商网站商品信息、新闻内容
3.计数器:访问排行榜、商品浏览数等和次数相关的数值统计场景
4.微博/微信社交场合:共同好友,粉丝数,关注,点赞评论等
5.消息队列:ELK的日志缓存、部分业务的订阅发布系统
6.地理位置: 基于GEO(地理信息定位),实现摇一摇,附近的人,外卖等功能
1.6 缓存的实现流程
数据更新操作流程:
数据读操作流程:
二、安装Redis
我的环境:
redis服务端:Node1
客户端:Node2
2.1 yum安装
yum安装redis需要epel源
[root@Node1 ~]#:yum install -y epel-release.noarch
[root@Node1 ~]#:yum install -y redis
[root@Node1 ~]#:systemctl start redis
[root@Node1 ~]#:systemctl status redis
● redis.service - Redis persistent key-value databaseLoaded: loaded (/usr/lib/systemd/system/redis.service; disabled; vendor preset: disabled)Drop-In: /etc/systemd/system/redis.service.d└─limit.confActive: active (running) since 一 2024-07-08 22:26:07 CST; 1s agoMain PID: 5449 (redis-server)Tasks: 3CGroup: /system.slice/redis.service└─5449 /usr/bin/redis-server 127.0.0.1:63797月 08 22:26:07 Node1 systemd[1]: Starting Redis persistent key-value database...
7月 08 22:26:07 Node1 systemd[1]: Started Redis persistent key-value database.
redis启动时,如果有错,也不会报错,查看状态看是否起来了
客户端工具:/usr/bin/redis-cli
配置文件:/etc/redis.conf
启动文件:/usr/bin/redis-server
日志文件:/var/log/redis
......
可以通过rpm -ql redis查看相关文件列表
由于yum安装的,版本太低了:
[root@Node1 ~]#:rpm -qi redis
Name : redis
Version : 3.2.12
......
2.2 编译安装
安装依赖包:
[root@Node1 ~]#:yum -y install gcc jemalloc-devel systemd-devel
创建/data/目录并进入目录:
[root@Node1 ~]#:mkdir /data/ ; cd /data
下载安装包:
[root@Node1 data]#:wget http://download.redis.io/releases/redis-5.0.7.tar.gz
解压并编译安装:
[root@Node1 data]#:tar xf redis-5.0.7.tar.gz
[root@Node1 data]#:cd redis-5.0.7/
[root@Node1 redis-5.0.7]#:make USE_SYSTEMD=yes PREFIX=/apps/redis install
配置环境变量:
[root@Node1 redis-5.0.7]#:echo 'PATH=/apps/redis/bin:$PATH' > /etc/profile.d/redis.sh
[root@Node1 redis-5.0.7]#:. /etc/profile.d/redis.sh
准备自定义的路径:
etc放配置文件
log放日志文件
data放数据文件
run放pid文件
[root@Node1 redis-5.0.7]#:mkdir /apps/redis/{etc,log,data,run}
把默认的配置文件复制到我们指定的路径下
[root@Node1 redis-5.0.7]#:cp /data/redis-5.0.7/redis.conf /apps/redis/etc/ -a
创建一个用户,并修改属主和属组权限
[root@Node1 redis-5.0.7]#:useradd -M -s /sbin/nologin redis
[root@Node1 redis-5.0.7]#:chown redis.redis /apps/redis -R
这时就可以通过redis-server启动起来了:只是前台启动,会影响当前操作,可以再开个终端
redis-server
redis-server --port 6379 #指定端口号,默认就是6379
redis-server /apps/redis/etc/redis.conf #也可以这样启动
可以切换到/apps/redis/下:cd /apps/redis
但我们是要systemd管理,自启动文件:
[root@Node1 redis]#:vim /usr/lib/systemd/system/redis.service
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/apps/redis/bin/redis-server /apps/redis/etc/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
#Type=notify 如果支持systemd可以启用此行
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
重新加载,并启动,查看状态是否启动起来:
[root@Node1 redis]#:systemctl daemon-reload
[root@Node1 redis]#:systemctl start redis
[root@Node1 redis]#:systemctl status redis
● redis.service - Redis persistent key-value databaseLoaded: loaded (/usr/lib/systemd/system/redis.service; disabled; vendor preset: disabled)Active: active (running) since 一 2024-07-08 22:54:33 CST; 5s agoMain PID: 9336 (redis-server)Tasks: 4CGroup: /system.slice/redis.service└─9336 /apps/redis/bin/redis-server 127.0.0.1:63797月 08 22:54:33 Node1 redis-server[9336]: | `-._`-._ _.-'_.-' |
7月 08 22:54:33 Node1 redis-server[9336]: `-._ `-._`-.__.-'_.-' _.-'
7月 08 22:54:33 Node1 redis-server[9336]: `-._ `-.__.-' _.-'
7月 08 22:54:33 Node1 redis-server[9336]: `-._ _.-'
7月 08 22:54:33 Node1 redis-server[9336]: `-.__.-'
7月 08 22:54:33 Node1 redis-server[9336]: 9336:M 08 Jul 2024 22:54:33.570 # WARNING: The TCP b...28.
7月 08 22:54:33 Node1 redis-server[9336]: 9336:M 08 Jul 2024 22:54:33.570 # Server initialized
7月 08 22:54:33 Node1 redis-server[9336]: 9336:M 08 Jul 2024 22:54:33.570 # WARNING overcommit...ct.
7月 08 22:54:33 Node1 redis-server[9336]: 9336:M 08 Jul 2024 22:54:33.570 # WARNING you have Tran...
7月 08 22:54:33 Node1 redis-server[9336]: 9336:M 08 Jul 2024 22:54:33.570 * Ready to accept co...ons
Hint: Some lines were ellipsized, use -l to show in full.
发现已经启动起来了!但有三个警告信息!
再去配置文件中指定一下路径文件位置:
[root@Node1 redis]#:vim /apps/redis/etc/redis.conf
......
bind 0.0.0.0 #使远端主机能够登录
......
logfile /apps/redis/log/redis.log #日志文件
......
dir /apps/redis/data/ #指定Redis服务器的工作目录
......
重启并查看状态
[root@Node1 redis]#:systemctl restart redis
[root@Node1 redis]#:systemctl status redis
● redis.service - Redis persistent key-value databaseLoaded: loaded (/usr/lib/systemd/system/redis.service; disabled; vendor preset: disabled)Active: active (running) since 一 2024-07-08 23:04:35 CST; 6s agoProcess: 9479 ExecStop=/bin/kill -s QUIT $MAINPID (code=exited, status=0/SUCCESS)Main PID: 9484 (redis-server)Tasks: 4CGroup: /system.slice/redis.service└─9484 /apps/redis/bin/redis-server 0.0.0.0:63797月 08 23:04:35 Node1 systemd[1]: Started Redis persistent key-value database.
2.3 处理redis的warning警告信息
一.backlog参数控制的是三次握手的时候server端收到client ack确认号之后的队列值,即全连接队列
二.0表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。1、表示内核允许分配所有的物理内存,而不管当前的内存状态如何。2、表示内核允许分配超过所有物理内存和交换空间总和的内存
三.警告:您在内核中启用了透明大页面(THP,不同于一般内存页的4k为2M)支持。 这将在Redis中造成延迟和内存使用问题。 要解决此问题,请以root 用户身份运行命令“echo never> /sys/kernel/mm/transparent_hugepage/enabled”,并将其添加到您的/etc/rc.local中,以便在重启后保留设置。禁用THP后,必须重新启动Redis。
[root@Node1 redis]#:vim /etc/sysctl.conf
net.core.somaxconn = 1024
vm.overcommit_memory = 1
[root@Node1 redis]#:sysctl -p
net.core.somaxconn = 1024
vm.overcommit_memory = 1
echo never > /sys/kernel/mm/transparent_hugepage/enabled #临时修改
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local #永久修改
重启:systemctl restart redis
查看:systemctl status redis
三、连接到Redis
3.1 本机无密码连接
在本机使用连接工具:redis-cli
如同打乒乓球,有去有回,ping pong
通过info能查看版本信息:5.0.7
3.2 本机密码连接
默认是无密码的:
设置密码,去配置文件,507行(命令行模式:507G跳转到507行)密码配置项时requirepass
[root@Node1 redis]#:vim etc/redis.conf
......
requirepass 123456
......
3.3 客户端连接
无密码连接:要加主机-h:
客户端有密码连接:
在服务端设置密码:
[root@Node1 redis]#:vim etc/redis.conf
......
requirepass 123456
......
[root@Node1 redis]#:systemctl restart redis
客户端通过-a选项,输入密码登录。
四、Redis多实例
在测试环境中经常使用多实例,需要指定不同实例的相应的端口,配置文件,日志文件等相关配置
范例:以编译安装为例实现redis多实例
可以共同使用一个配置文件,建议分开,写成多个文件
多实例实验:以端口号区分不同的redis
把原来的默认的redis关闭。systemctl stop redis
手动写三个端口的redis,6381,6382,6383
使用端口号登录redis
把配置文件复制三份redis6381
4.1 修改配置文件
对以下配置项做出修改:
[root@Node1 redis]#:cp etc/redis.conf etc/redis6381.conf -a
[root@Node1 redis]#:vim etc/redis6381.conf
......
pidfile /apps/redis/run/redis6381.pid
......
logfile /apps/redis/log/redis6381.log
......
dbfilename dump6381.rdb
......
dir /apps/redis/data/
......
port 6381
......
有以下修改,dir /apps/redis/data/不做修改。工作目录就放在/data/下
复制第二个文件:redis6382
[root@Node1 redis]#:cp etc/redis6381.conf etc/redis6382.conf -a
[root@Node1 redis]#:vim etc/redis6382.conf
......
:%s/6381/6382/g
查看6382:
复制第三个文件:redis6383
[root@Node1 redis]#:cp etc/redis6381.conf etc/redis6383.conf -a
[root@Node1 redis]#:vim etc/redis6383.conf
......
:%s/6381/6383/g
查看6383:
4.2 修改service文件
[root@Node1 redis]#:cd /lib/systemd/system
[root@Node1 system]#:cp redis.service redis6381.service -a
[root@Node1 system]#:cp redis.service redis6382.service -a
[root@Node1 system]#:cp redis.service redis6383.service -a
[root@Node1 system]#:
#修改6381
[root@Node1 system]#:vim redis6381.service
......
ExecStart=/apps/redis/bin/redis-server /apps/redis/etc/redis6381.conf --supervised systemd
......
#修改6382
[root@Node1 system]#:vim redis6382.service
......
ExecStart=/apps/redis/bin/redis-server /apps/redis/etc/redis6382.conf --supervised systemd
......
#修改6383
[root@Node1 system]#:vim redis6383.service
......
ExecStart=/apps/redis/bin/redis-server /apps/redis/etc/redis6383.conf --supervised systemd
......
修改完service文件,将启动对应的文件。
先tree查看一下路径下的配置文件:配置文件etc/下多了三个配置文件,我们自行修改的。
[root@Node1 redis]#:tree
.
├── bin
│ ├── redis-benchmark
│ ├── redis-check-aof
│ ├── redis-check-rdb
│ ├── redis-cli
│ ├── redis-sentinel -> redis-server
│ └── redis-server
├── data
│ └── dump.rdb
├── etc
│ ├── redis6381.conf
│ ├── redis6382.conf
│ ├── redis6383.conf
│ └── redis.conf
├── log
│ └── redis.log
└── run5 directories, 12 files
启动三个配置文件:
tree,查看文件路径:
日志和pid文件自动生成!
[root@Node1 redis]#:tree
.
├── bin
│ ├── redis-benchmark
│ ├── redis-check-aof
│ ├── redis-check-rdb
│ ├── redis-cli
│ ├── redis-sentinel -> redis-server
│ └── redis-server
├── data
│ └── dump.rdb
├── etc
│ ├── redis6381.conf
│ ├── redis6382.conf
│ ├── redis6383.conf
│ └── redis.conf
├── log
│ ├── redis6381.log
│ ├── redis6382.log
│ ├── redis6383.log
│ └── redis.log
└── run├── redis6381.pid├── redis6382.pid└── redis6383.pid5 directories, 18 files
要查看一下状态:
都启动起来了,本机登录测试:指定端口号
---end---