redis 运维讲解01

运维不需要往里面存数据,但是需要搭建、备份、扩容、收缩都是运维的工作,保证 redis 不能宕机、备份数据、协助开发查询数据

一、为什么需要redis

1、传统架构

​app  →  DAL(DAL(数据访问层) ,其功能主要是负责数据库的访问。简单地说就是实现对数据表的Select(查询)、Insert(插入)、Update(更新)、Delete(删除)等操作。)→ JDBC 统一了所有平台(JDBC是什么? Java DataBase Connectivity(Java语言连接数据库) 

​2、数据库架构的演变

mysql  →  mysql 主从 →  Memcached(轻量级缓存中间件) + Mysql主从 + mysql 垂直拆分(分库分表、读写分离)  → redis (重量级缓存中间件) + Mysql主从 + mysql 垂直拆分 。其中 redis 缓存中间件中间件,比如一个网站80% 都在读, select 查询语句每次都去数据库查,数据库压力很大,减轻压力使用缓存,将经常查询的语句存在 redis 中,下次再查询直接到 redis 中 

发展过程:优化数据库结构和索引,还是有压力 →  转变成文件( IO) 存储,最后还是有压力 →  Memcached (缓存),数据量大还是不行 → redis  

3、NoSQL

redis 是一个key value 类型的NoSQL(not only sql),主要存储简单的key 和 value,最常用的就是set get ,存入读取。对应的 mongodb 也是NoSQL,是文档类型的数据库,也是类似存储的key 和 value,对比 redis ,value 存储的是结构化数据,不是简单的数据

二、 redis 特性

redis 支持网络(可以基于网络协议传输一些东西)、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API(java、python、php等所有语言对接)。

1、作用

1、内存存储、持久化,内存中是断电即丢失。所以说持久化很重要,redis 从内存持久化到本地的两种模式 ( rdb, aof ) 
2、高效率、可以 用于高速 缓存
3、发布订阅系统
4、地图信息分析
5、计时器、计数器 ( 微信微博的浏览量,数据通过 redis ,redis 会计数,不需要存入从数据库中)
6、提供pipeline功能,客户端将一批命令一次性传到Redis,减少网络开销

2、特性

多样的数据类型、持久化、集群、跨语言API调用(python 语言部门,做后台日志、后台分析、前台java)、事务、高可用和分布式 ( 哨兵、集群 ) 与生俱来的自带的,mysql 的 MHA 、Mycat 不是 mysql 自己的

3、应用场景

1、缓存-建过期时间,比如网页登录的信息,在一定时间登录后,一段时间内不需要登录。他是缓存的session会话,并设置过期时间,过期后缓存用户信息找不到再去mysql 查,查到然后再返回给redis存储,并继续在设置建过期时间。一般研发架构的时候会存储的热数据,非热数据访问量少还是直接去mysql,防止 redis 数据量 太大,内存占用高,影响其他。比如优惠券,在一段时间后会过期

2、排行榜 - 列表&有序集合

点击数最大的帖子,点击量通过 redis 存储,redis会自动排序这些数值,将最大的置顶最前端,实现热度排名。还可以发布时间做排行榜,按照时间做排序

3、计数器:帖子的阅读数、视频播放数等、商品浏览数,time key1 ,访问一次帖子,就会将key1 的value+1

4、Redis设置阈值,访问量达到一定后拒绝访问。实现拒绝恶意刷帖跟IP攻击,限制访问次数大的IP,中用redis,key是访问用户的ip地址,value是单位时间内访问次数,超过阈值,就给用户提示访问过于频繁,拒绝访问。但这种缺点很明显,就是有很多的代码开发量,对原有业务代码侵入性太强,所有实用价值我个人觉得不是太高

5、社交网络-集合(差集、并集、交集)

踩、赞,粉丝,共同好友/喜好,推送,打标签。比如 A 的兴趣组合A (篮球、足球、音乐), B 的兴趣组合B (Linux、运维、音乐)。B会跟A做集合取出交集(音乐),告诉A有一个B也喜欢音乐。比如将所有的用户进行交集,筛选出(音乐),筛选出这些告诉有一个新的音乐发版。

6、消息队列发布订阅:redis可以做消息队列,Redis提供了两种方式来做消息队列,一种是生产消费模式,另一种是发布订阅模式。应用于MQ,或者给ELK做缓存,实现消息队列机制(常用)

4、官网

http://www.redis.cn/

三 、redis 部署

目录规划

# redis 下载目录
/opt/src

# redis安装目录
/opt/redis_cluster/redis_[post]/{conf,pid,logs}

# redis 数据目录
/data/redis_cluster/redis_[post]/redis.[post].rdb

# redis 运维脚本
/root/scripts/redis_shell.sh

安装部署

[root@86-5-master ~]# mkdir /data/redis_cluster/redis_6379 -p
[root@86-5-master ~]# mkdir /opt/redis_cluster/redis_6379/{conf,pid,logs} -p
[root@86-5-master ~]# tree /opt/redis_cluster/
/opt/redis_cluster/
└── redis_6379
    ├── conf
    ├── logs
    └── pid

[root@86-5-master ~]# mkdir /opt/src;cd /opt/src
[root@86-5-master src]# wget https://download.redis.io/releases/redis-6.0.16.tar.gz
[root@86-5-master src]# tar -zxvf redis-6.0.16.tar.gz -C /opt/redis_cluster/
[root@86-5-master src]# cd /opt/redis_cluster/
[root@86-5-master redis_cluster]# ln -s redis-6.0.16/ redis
[root@86-5-master redis_cluster]# ll
lrwxrwxrwx 1 root root   13 10月 22 10:30 redis -> redis-6.0.16/
drwxrwxr-x 7 root root 4096 10月  4 2021 redis-6.0.16
drwxr-xr-x 5 root root   41 10月 22 10:26 redis_6379

[root@86-5-master redis_cluster]# cd redis
[root@86-5-master redis]# cd redis
[root@86-5-master redis]# gcc -v   # 查看gcc版本,redis是c++写的,所以依赖gcc,redis-6.0.16版本要大于gcc version 5.3,否则编译出错

# 为了防止gcc版本低,升级gcc,升级到 5.3及以上版本
# 直接通过yum install gcc安装的版本4.8.5太老了,很多新的库的用不起,没办法,只有升级了。手动编译安装太过于麻烦
# 在安装过程中需要依赖yum源,所以建议配置阿里云的yum源
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils 
scl enable devtoolset-9 bash
gcc --version
 
[root@86-5-master redis]# make   # gcc版本无问题后,make编译,make是产生可执行的二进制文件,为此目录中已经存在Makefile,所以不用./configure
[root@86-5-master redis]# ll /usr/local/bin/
总用量 0
[root@86-5-master redis]# make install  # 将可执行而二进制文件复制到/usr/local/bin下
[root@86-5-master redis]# ll /usr/local/bin/
总用量 38208
-rwxr-xr-x 1 root root 4746280 10月 22 10:46 redis-benchmark
-rwxr-xr-x 1 root root 9767024 10月 22 10:46 redis-check-aof
-rwxr-xr-x 1 root root 9767024 10月 22 10:46 redis-check-rdb
-rwxr-xr-x 1 root root 5069712 10月 22 10:46 redis-cli
lrwxrwxrwx 1 root root      12 10月 22 10:46 redis-sentinel -> redis-server
-rwxr-xr-x 1 root root 9767024 10月 22 10:46 redis-server

如果出现 make 出现如下结果,说明是gcc版本太低,需要升级到大于gcc version 5.3,比如 gcc version 9.3.1

make install 安装后,安装在/usr/local/bin/

[root@86-5-master redis]# ll /usr/local/bin/
总用量 38208
-rwxr-xr-x 1 root root 4746280 10月 22 10:46 redis-benchmark  # 测试性能的 
-rwxr-xr-x 1 root root 9767024 10月 22 10:46 redis-check-aof  # 内存数据持久化到磁盘的模式之一aof
-rwxr-xr-x 1 root root 9767024 10月 22 10:46 redis-check-rdb  # 内存数据持久化到磁盘的模式之一rdb
-rwxr-xr-x 1 root root 5069712 10月 22 10:46 redis-cli        # 客户端
lrwxrwxrwx 1 root root      12 10月 22 10:46 redis-sentinel -> redis-server   # 哨兵
-rwxr-xr-x 1 root root 9767024 10月 22 10:46 redis-server     # 服务端

如何启动 redis,包括 redis 的配置文件在哪,redis 生成目录文件在哪 ,官方给出 install_server.sh 脚本,协助你初始化产品。比如如下,注意我们使用默认的配置路径,只是做演示查看。

[root@86-5-master redis]# cd utils
[root@86-5-master utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379]     # 输入redis的端口号
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]   # redis的配置文件
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]   # redis的日志
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379] # redis的数据目录
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server] # 可执行文件的路径
Selected config:
Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
Executable     : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!

运行此脚本后,redis还会将服务后台启动,可以将其关闭,我们不适用默认的,这个作为演示
[root@86-5-master logs]# ps -ef |grep redis
root      8609     1  0 11:42 ?        00:00:02 /usr/local/bin/redis-server 127.0.0.1:6379
root     10471  3058  0 12:19 pts/0    00:00:00 grep --color=auto redis
[root@86-5-master logs]# redis-cli -p 6379
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> shutdown
not connected> exit

期间可能会有报错

解决:

打开install_server.sh文件

vim ./install_server.sh

注释报错内容

再次执行即可成功

原因:以上问题只是一种不需要systemd的安装方式,如果需要用systemd方式来启动redis服务,不注释也是也可的。

大致看一下 redis 的配置文件

[root@86-5-master utils]# grep -v "^#\|^$" /etc/redis/6379.conf 
bind 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis_6379.log
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir /var/lib/redis/6379
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
[root@86-5-master utils]# 

我们不需要这么多,只用一些参数即可,自定义配置 redis 的配置文件

[root@86-5-master utils]# cat /opt/redis_cluster/redis_6379/conf/redis_6379.conf
### 绑定的主机地址,后续会做演示
### 如果不写127.0.0.1, 本地 redis-cli 必须指定-h 192.168.86.5
### 如果将127.0.0.1放在前面,主从备连接失败报错Error condition on socket for SYNC: Connection refused
bind 192.168.86.5 127.0.0.1
### 监听的端口
port 6379
### 以守护进程启动,如果为no,redis启动后挂载在前台,退出shell后就会关闭
daemonize yes
### redis进程启动后,redis进程的pid文件的保存地址
pidfile /opt/redis_cluster/redis_6379/pid/redis_6379.pid
### log文件保存的地址
logfile /opt/redis_cluster/redis_6379/logs/redis_6379.log
### 设置数据库的数量,默认为0,最大使用16个数据库,默认登录redis后使用数据库0,后期集群只用一个数据库0
databases 16
### 指定本地持久化文件的文件名,默认是dump.rdb,只写文件说明是在相对路径下,
### 相对目录dir下,dir /data/redis_cluster/redis_6379下dbfilename redis_6379.rdb
dbfilename redis_6379.rdb
### 本地数据库的目录
dir /data/redis_cluster/redis_6379

redis 启动

通过指定的配置文件启动服务
[root@86-5-master ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf
[root@86-5-master ~]# ps -ef |grep redis
root     10521     1  0 12:20 ?        00:00:00 redis-server 127.0.0.1:6379
root     10559  3058  0 12:21 pts/0    00:00:00 grep --color=auto redis

[root@86-5-master logs]# tail -n 4 /opt/redis_cluster/redis_6379/logs/redis_6379.log
10521:C 22 Oct 2022 12:20:40.907 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
10521:C 22 Oct 2022 12:20:40.907 # Redis version=6.0.16, bits=64, commit=00000000, modified=0, pid=10521, just started
10521:C 22 Oct 2022 12:20:40.907 # Configuration loaded
10521:M 22 Oct 2022 12:20:40.910 * Increased maximum number of open files to 10032 (it was originally set to 1024).

验证是否启动

[root@86-5-master opt]# redis-cli -p 6379   # -p 指定端口,-h 指定连接哪个IP下的redis,默认不写-h 为本机
127.0.0.1:6379> ping  # ping 返回 pong ,代表 redis 无问题
PONG

[root@86-5-master ~]# ps -ef |grep redis
root     10953     1  0 12:28 ?        00:00:00 redis-server 127.0.0.1:6379
root     11141  3058  0 12:32 pts/0    00:00:00 redis-cli -p 6379 -h 127.0.0.1   # ps 中显示当前占用的进程
root     11149  9249  0 12:32 pts/1    00:00:00 grep --color=auto redis

解释 bind 127.0.0.1 192.168.86.5  ### 绑定的主机地址

1、如果配置的是bind 127.0.0.1 192.168.86.5,则redis启动后,显示的是如下redis-server 127.0.0.1:6379

[root@86-5-master ~]# ps -ef |grep redis
root     10953     1  0 12:28 ?        00:00:00 redis-server 127.0.0.1:6379
root     11149  9249  0 12:32 pts/1    00:00:00 grep --color=auto redis

2、如果配置的是bind 192.168.86.5 127.0.0.1 ,则redis启动后,显示的是如下redis-server 192.168.86.5:6379

[root@86-5-master ~]# ps -ef |grep redis
root     10953     1  0 12:28 ?        00:00:00 redis-server 192.168.86.5:6379
root     11149  9249  0 12:32 pts/1    00:00:00 grep --color=auto redis

总结:谁在前面,就显示谁的IP

3、bind有什么用,bind必须配置的是本机的能访问的IP,否则无法启动。bind 代表的是redis依赖那个网卡启动(ifconfig)。
比如说配置的的是bind 192.168.86.5,则使用redis-cli -p 6379 是登录不了的,因
为redis-cli -p 6379 默认使用的是redis-cli -p 6379 -h 127.0.0.1。现在redis是依赖192.168.86.5的网卡,所以只有指定-h 是192.168.86.5,才能代表登录的是我的redis。相反,比如说配置的的是bind 127.0.0.1,只有redis-cli -p 6379 -h 192.168.86.5才能登陆

4、bind 192.168.86.5 127.0.0.1 则说明redis依赖于两个网卡启动,所以redis-cli -p 6379 -h 192.168.86.5  redis-cli -p 6379 -h 127.0.0.1 都可以登录

5、具体的详细讲解查看 https://blog.csdn.net/Jerry00713/article/details/127460471

关闭 redis 服务

[root@86-5-master ~]# redis-cli -p 6379  
127.0.0.1:6379> shutdown
not connected> exit
[root@86-5-master ~]# ps -ef |grep redis
root     12613  9249  0 13:02 pts/1    00:00:00 grep --color=auto redis

# redis-cli 跟 mysql 一样,也是可以后面接命令
[root@86-5-master ~]# redis-cli -p 6379 shutdown

官方也给了重启 redis 的脚本,也是通过 redis-cli  shutdown 等,为什么不用这个脚本,此脚本只能管理一台redis,因为我们后期使用多实例,后期可以自己写脚本

[root@86-5-master ~]# cat /etc/init.d/redis_6379 
#!/bin/sh
#Configurations injected by install_server below....

EXEC=/usr/local/bin/redis-server
CLIEXEC=/usr/local/bin/redis-cli
PIDFILE=/var/run/redis_6379.pid
CONF="/etc/redis/6379.conf"
REDISPORT="6379"
###############
# SysV Init Information
# chkconfig: - 58 74
# description: redis_6379 is the redis daemon.
### BEGIN INIT INFO
# Provides: redis_6379
# Required-Start: $network $local_fs $remote_fs
# Required-Stop: $network $local_fs $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Should-Start: $syslog $named
# Should-Stop: $syslog $named
# Short-Description: start and stop redis_6379
# Description: Redis daemon
### END INIT INFO


case "$1" in
    start)
        if [ -f $PIDFILE ]
        then
            echo "$PIDFILE exists, process is already running or crashed"
        else
            echo "Starting Redis server..."
            $EXEC $CONF
        fi
        ;;
    stop)
        if [ ! -f $PIDFILE ]
        then
            echo "$PIDFILE does not exist, process is not running"
        else
            PID=$(cat $PIDFILE)
            echo "Stopping ..."
            $CLIEXEC -p $REDISPORT shutdown
            while [ -x /proc/${PID} ]
            do
                echo "Waiting for Redis to shutdown ..."
                sleep 1
            done
            echo "Redis stopped"
        fi
        ;;
    status)
        PID=$(cat $PIDFILE)
        if [ ! -x /proc/${PID} ]
        then
            echo 'Redis is not running'
        else
            echo "Redis is running ($PID)"
        fi
        ;;
    restart)
        $0 stop
        $0 start
        ;;
    *)
        echo "Please use start, stop, restart or status as first argument"
        ;;
esac
[root@86-5-master ~]# 

可以使用域名解析登录 

[root@86-5-master ~]# grep "bind" /opt/redis_cluster/redis_6379/conf/redis_6379.conf 
bind 192.168.86.5 127.0.0.1

[root@86-5-master ~]# hostname
86-5-master
[root@86-5-master ~]# cat /etc/hosts
192.168.86.5 86-5-master

[root@86-5-master ~]# redis-cli -p 6379 -h 86-5-master 
86-5-master:6379> 

四 、Redis压测工具(redis-benchmark)

Redis 自带了一个叫 redis-benchmark 的工具来模拟 N 个客户端同时发出 M 个请求。(类似于 Apache ab 程序)

1、redis-benchmark参数

使用 redis-benchmark -h 命令来查看使用参数

redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests]> [-k <boolean>]
 
 -h <hostname> 指定服务器主机名 (默认 127.0.0.1)
 -p <port> 指定服务器端口 (默认 6379)
 -s <socket> 指定服务器 socket
 -a <password> Redis 认证密码
 -c <clients> 指定并发连接数 (默认 50)
 -n <requests> 指定请求数 (默认 100000),配合-c默认50,则默认请求数为5000000
 -d <size> 以字节的形式指定 SET/GET 值的数据大小 (默认 3),真对写入\读取,每次只写入\读取3个字节
 --dbnum <db> 选择指定的数据库号 (默认 0)
 -k <boolean> 1=keep alive 0=reconnect (默认 1),默认保证只有一台redis服务器处理请求
 -r <keyspacelen> SET/GET/INCR 使用随机 key, SADD 使用随机值
 -P <numreq> 通过管道传输 <numreq> 请求 (no pipeline)
 -q 退出,仅显示 query/sec 值
 --csv 以 CSV 格式输出
 -l 生成循环,永久执行测试
 -t <tests> 仅运行以逗号分隔的测试命令列表
 -I Idle 模式,仅打开 N 个 idle 连接并等待

测试:100个并发连接,100000请求

redis-benchmark -h localhost -p 6379 -c 100 -n 100000

2、执行后内容的解释

会发现有PING、SET、GET、INCR 等等

====== SET ======  # 对redis进行SET,set是写入的意思,所以此压力测试为对所有的集合进行写入测试
  100000 requests completed in 2.12 seconds  # 100000个请求,用了2.12s
  100 parallel clients   # 100个并行的客户端访问
  3 bytes payload        # 每次只写入3个字节
  keep alive: 1          # 保证只有一台redis服务器处理请求

41.69% <= 1 milliseconds  # 第一秒的时候已经处理了41.69%
94.69% <= 2 milliseconds  # 第二秒的时候已经处理了94.69%
99.63% <= 3 milliseconds  # 第三秒的时候已经处理了99.63%
100.00% <= 3 milliseconds # 所有请求在3~4s内处理完毕
47125.36 requests per second # 每秒处理47125.36个请求

# 保证只有一台redis服务器处理请求,期间单纯一台客户端每次写入3个字节,发送100000个请求,用
# 了2.12s,如果有100个客户端同时并行每次写入3个字节,每个发送100000个请求,一共在3~4s内处
# 理完毕,平均每秒处理47125.36个请求

====== GET ======
  100000 requests completed in 2.19 seconds
  100 parallel clients
  3 bytes payload
  keep alive: 1

40.87% <= 1 milliseconds
94.12% <= 2 milliseconds
99.76% <= 3 milliseconds
100.00% <= 3 milliseconds
45682.96 requests per second

压测后,会在0号数据库中记录信息

[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> keys *
1) "key:__rand_int__"
2) "mylist"
3) "counter:__rand_int__"
4) "myset:__rand_int__"
5) "name"

五、redis 常用概念

1、redis 是单线程还是多线程

Redis 6.0版本之前的单线程指的是其网络I/O和键值对读写是由一个线程完成的,什么意思

Redis客户端1发送set命令 → Redis服务端处理 →服务端返回ok,
Redis客户端2发送set命令 → Redis服务端处理 →服务端返回ok,
期间 Redis 服务端,先接受到Redis客户端1发送set命令后,则会堵塞,让其他的命令进行排队,直到处理完,给Redis客户端1发送OK后,在继续执行后传递过来的Redis客户端2发送set命令,所以在服务端是由一个线程操作的,叫做单线程

Redis6.0引入的多线程指的是网络请求过程采用了多线程,而键值对读写命令仍然是单线程处理的,什么意思

Redis客户端1发送set命令 → Redis服务端处理 →服务端返回ok,
Redis客户端2发送set命令 → Redis服务端处理 →服务端返回ok,
期间 Redis 服务端,先接受到 Redis 客户端1发送set命令后,还是会堵塞,让其他的命令进行排队,但当服务端处理完后,则会接受后传递过来的Redis客户端2发送set命令,期间给Redis客户端1发送OK这个工作,是由CPU的线程处理,我们称之为多线程,但 Redis 服务端处理的还是单线程。所以Redis依然是并发安全的,因为命令的执行还是一个一个顺序的执行。
也就是只有网络请求模块和数据操作模块是单线程的,而其它的持久化、集群数据同步等,其实是由额外的线程执行的

2、redis 为什么单线程还能这么快

1.命令执行基于内存操作,一条命令在内存里操作的时间是几十纳秒
2.命令执行是单线程操作,没有线程切换开销
3.基于IO多路复用机制提升Redis的IO利用率
4.高效的数据存储结构:全局hash表以及多种高效数据结构,比如:跳表,压缩列表,链表等等。什么意思?Redis底层 存储数据是用了一张全局的 HASH 表,HASH是由一维的数组和二维的链表
Hash表 的是时间复杂度实际上是一个常量,效率相当的高,比如执行set zhuge 666,如何存储在Hash表中,对key做hash运算hash(zhuge)得到的数值,在与全局hash表的长度做一个取模,最后一定是落到一个一维数组中的一个位置,将会把对应的key 和 value 放入到链表中,如果有多个key,则有少概率会存在同一个数组上,次数据会接着之前的数据放在链表后多

3redis IO 多路复用

4、redis 底层数据如何用跳表来存储的

redis 本身有一个有集合zset,他内部的存放的元素,就是一个元素加上一个分值,那就对于有序集合zsat 来说,他底层是可以用跳表来存储的,当然也可以用压缩列表来存储的。如果使用跳表来存储的,他是什么,我么最早实际上是吧我们的有序集合会放到一个列表中,列表时按照我们每个元素的分值从小到大,从左到右依次进行排序,就比如 a:1  c:3  b:5 排序

链表有个特点,你插入元素比较快,比如插入30 分值的元素,你只需要将 25 的下一个元素的指针指向30,30的下一个元素的指针指向32。但是查找是比较慢的,比如查找链表尾部的元素,需要链表的比表头按照指针逐个遍历,知道找到最后的这个元素,效率比较低

正所以如此,底层对链表做了一些优化,给我们建立索引层,链表中的每两个元素的第一个 元素,往上见一个 冗余的元素,就是索引元素。这终结构查找元素,从跳表的左上角开始查,比如说32,可以按照折半去查,针对于查找也就是mysql 的 b+树 思想

 

 

六、redis 命令

Redis 的五大数据类型(String 、 List、 Set、 Hash、 Zset)

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件MQ发布订阅。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置主从 复制(replication)LUA脚本(Lua scripting), LRU驱动事件(LRU eviction)事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

一、全局命令 

1、keys * 

查看当前数据库下的所有到的 key注意此命令很危险,redis 数据是加载到内存中的,执行后,将所有的内存中的 key 都列出来,如果十几个G的数据,redis 直接宕机,只能 kill 掉进程重启,重启后可以翻阅之前的执行记录,能显示出执行了keys *

[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> keys *    # 查看全部的key
(empty array)             # 代表此时没有任何key 

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379>

2、Dbsize

查看 key 键的总数,一条 key 大小为 1,dbsize 命令在计算键值总数时不会便利所有键,而是直接获取Redis内置的键总数变量

查看数据库大小dbsize,一条set为1,两条就是2
127.0.0.1:6379[3]> dbsize
(integer) 0 
127.0.0.1:6379[3]> set name nihao
OK
127.0.0.1:6379[3]> dbsize
(integer) 1

3、EXISTS key 

检查键是否存在,存在返回1,不存在返回0

127.0.0.1:6379> set name1 value1
OK
127.0.0.1:6379> EXISTS name1    # 判断当前数据库下,此key是不是存在
(integer) 1
127.0.0.1:6379> EXISTS name
(integer) 0

4、Del key [key...]

删除键,通用命令,无论值是什么类型数据结构 ,del命令都可以将其删除

127.0.0.1:6379> set name1 value1
OK
127.0.0.1:6379> EXISTS name1    # 判断当前数据库下,此key是不是存在
(integer) 1
127.0.0.1:6379> EXISTS name
(integer) 0

5、Expire  key seconds

键过期,Redis 支持对键添加过期时间,当超过过期时间后,会自动删除键。

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK

127.0.0.1:6379> EXPIRE k1 10     # 设置10s后 k1 过期
(integer) 1
127.0.0.1:6379> TTL k1  
(integer) 3                      # 剩余3s过期
127.0.0.1:6379> TTL k1
(integer) -2                     # -2 代表没有这个key,也说明已经过期后key删除
127.0.0.1:6379> TTL k3           # -2 代表没有这个key
(integer) -2

127.0.0.1:6379> TTL k2           # -1 代表永不过期 
(integer) -1
127.0.0.1:6379> 

6、ttl key

通过 ttl 命令 查看键过期剩余时间。TTL是 Time To Live的缩写,在ping中该字段指定IP包被路由器丢弃之前允许通过的最大网段数量

127.0.0.1:6379> set name1 value1
OK
127.0.0.1:6379> keys *
1) "name1"
127.0.0.1:6379> EXPIRE name1 10 # 设置10s后name1 过期
(integer) 1
127.0.0.1:6379> ttl name1
(integer) 4    # 剩余4s 过期
127.0.0.1:6379> ttl name1
(integer) -2    # -2代表过期

7、PERSIST

将已经在过期的 key 设置成永久

127.0.0.1:6379> EXPIRE k2 100
(integer) 1
127.0.0.1:6379> TTL k2
(integer) 96
127.0.0.1:6379> PERSIST k2
(integer) 1
127.0.0.1:6379> TTL k2
(integer) -1
127.0.0.1:6379> 

8、Type

查看键的数据类型

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 20
OK
127.0.0.1:6379> TYPE k1
string
127.0.0.1:6379> TYPE k2
string

9、SELECT

切换数据库

1、redis默认有16个数据库,默认使用第0个数据库,如何切换
127.0.0.1:6379> select 7    # 切换到数据库7
OK
127.0.0.1:6379[3]>          # 对应的显示[3]代表数据库3

10、flushall   flushdb

清空所有数据库flushall、清空当前库flushdb,注意此命令很危险

清空所有数据库flushall、清空当前库flushdb
127.0.0.1:6379> select 3
OK
127.0.0.1:6379[3]> keys *
1) "name1"
2) "name"
127.0.0.1:6379[3]> flushdb
OK
127.0.0.1:6379[3]> keys *
(empty list or set)

11、move 

move  key数值 数据库

# 表示将当前数据库下的key数值移动到那个数据库下, move  key数值   数据库
# 高可用集群模式下不支持移动,同时只能使用一个库

127.0.0.1:6379> set name1 value1
OK
127.0.0.1:6379> move name1 3   
(integer) 1
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> select 3
OK
127.0.0.1:6379[3]> keys *
1) "name1"
127.0.0.1:6379[3]> 

二、字符串类型下的命令

1、set key value

录入 key value

[root@86-5-master ~]# redis-cli -p 6379
127.0.0.1:6379> set k1 v1
OK

2、get key 

获取 key 的 value

127.0.0.1:6379> get k1 
"v1"
127.0.0.1:6379> 

3、数字、字符串在redis中都是字符串

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 20
OK
127.0.0.1:6379> TYPE k1
string
127.0.0.1:6379> TYPE k2
string

4、incr key

incr key数值  # 执行一次 incr,则将 key 对应的 value 数值 +1

实现:计数器功能,在浏览器的访问量的代码中,访问数据库网页,执行一次 (incr  网页显示访问量的 key),get 获取就可显示访问量,实现计数功能,最后可以持久化落盘

注意:incr 后接着没有的key,会先创建,redis严格区分大小写

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> get views
"1"
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> incr views
(integer) 3
127.0.0.1:6379> get views
"3"
127.0.0.1:6379
如果设置value非数字,则执行 incr 后报错
127.0.0.1:6379> set views a
OK
127.0.0.1:6379> incr views
(error) ERR value is not an integer or out of range
127.0.0.1:6379> 

5、INCRBY key setp

INCRBY key数值  步长  # 执行一次 INCRBY , value  = value + 步长

实现:计数器功能,在浏览器的访问量,可以直接修改后台数据

注意:INCRBY 后接着没有的key,会先创建,redis严格区分大小写

127.0.0.1:6379> get k2
"20"
127.0.0.1:6379> INCRBY k2 100
(integer) 120
127.0.0.1:6379> get k2
"120"
127.0.0.1:6379> 

6、decr key

decr key数值  # 执行一次 decr ,则将 key对应的 value 数值 -1

注意:decr 后接着没有的key,会先创建,redis严格区分大小写

127.0.0.1:6379> get views
"1"
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> decr views
(integer) -1
127.0.0.1:6379> get views
"-1"
127.0.0.1:6379>
 
127.0.0.1:6379> set views a
OK
127.0.0.1:6379> decr views
(error) ERR value is not an integer or out of range
127.0.0.1:6379> 

7、DECRBY

DECRBY key数值  步长  # 执行一次 INCRBY , value  = value - 步长

注意:DECRBY 后接着没有的key,会先创建,redis严格区分大小写

127.0.0.1:6379> get k2
"120"
127.0.0.1:6379> DECRBY k2 20
(integer) 100
127.0.0.1:6379> get k2
"100"
127.0.0.1:6379> 

8、MSET  

MSET key1 value1 key2 value2   # 批量 set 插入多个,如果插入的元素有重复的key,redis则会覆盖之前的key value

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> mset k1 v3 k2 v2
OK
127.0.0.1:6379> get k1
"v3"
127.0.0.1:6379> 

9、MGET 

MGET key1 key2 key3  # 批量 get 获取

注意:redis 不能 进行模糊范围查询,比如 get key1~key3 只能通过写脚本

127.0.0.1:6379> MGET k1 k2
1) "v3"
2) "v2"
127.0.0.1:6379> MGET k5   # 如果没有,返回nil
1) (nil)
127.0.0.1:6379> 

10、EXISTS key

 EXISTS key数值     # 判断当前数据库下,此 key 是不是存在

127.0.0.1:6379> set name1 value1
OK
127.0.0.1:6379> EXISTS name1    # 判断当前数据库下,此key是不是存在
(integer) 1
127.0.0.1:6379> EXISTS name
(integer) 0

11、DEL key

# 删除 key

127.0.0.1:6379> set name1 value1
OK
127.0.0.1:6379> EXISTS name1    # 判断当前数据库下,此key是不是存在
(integer) 1
127.0.0.1:6379> EXISTS name
(integer) 0

12、SETNX

SETNX key value  #  如果当前库中存在这个 key ,则不进行操作。如果当前库中存在这个 key ,则进行SET​​ key value。在分布式锁中常常使用,保证当前的数值是存在的,乐观锁也可以加进去

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> SETNX k1 value1
(integer) 0
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> SETNX k3 value3
(integer) 1
127.0.0.1:6379> get k3
"value3"
127.0.0.1:6379> 

13、msetnx 

msetnx key1 value1 key2 value3   # 批量 setnx 设置,setnx是判断不存在,进行 set 注意如果参数中有一个key已经存在,setnx是不会修改,但会影响其他的key也失败,即使其他的key是不存在。因为要保证原子性(要不都成功要不都失败)。所以分布式锁使用这种很好 ,分布式锁要依赖原子性

127.0.0.1:6379> msetnx k1 v1 k4 v4
(integer) 0            # 0 代表没有执行成功
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
 
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> msetnx k1 value1 k4 v4
(integer) 0           # 0 代表没有执行成功
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> 

14、getset

getset key value  #  这个命令可以理解为先 get 在 set ,如果 get 不存在返回(nil),然后再 set key。如果存在返回 value 数值,然后再执行 set  修改。可以做判断,如果 get 等于此数值,在判断改不改

127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb
"redis"
127.0.0.1:6379> get db
"mongodb"
127.0.0.1:6379> 

15、SETRANGE 

SETRANGE key数值 下标起始位置  #  替换字符串

127.0.0.1:6379> set key2 "abcdefg"
OK
127.0.0.1:6379> STRLEN key2
(integer) 7
127.0.0.1:6379> SETRANGE key2 1 xx   # 将下标是1的位置起始点进行替换为xx
(integer) 7
127.0.0.1:6379> get key2
"axxdefg"
127.0.0.1:6379> 

16、GETRANGE 

GETRANGE  key数值 下标范围 #  截取字符串范围

127.0.0.1:6379> set key1 "hello,world"
OK
127.0.0.1:6379> get key1
"hello,world"
127.0.0.1:6379> GETRANGE key1 0 3   # 截取下标是0~3
"hell"
127.0.0.1:6379> get key1
"hello,world"
127.0.0.1:6379> GETRANGE key1 0 -1  # 截取全部字符串 -1 代表从后往前走,第一个数值是-1
"hello,world"
127.0.0.1:6379> GETRANGE key1 0 -2
"hello,worl"
127.0.0.1:6379> 

17、STRLEN

STRLEN key数值# 获取字符串长度

127.0.0.1:6379> get name1
"value1,hello"
127.0.0.1:6379> STRLEN name1
(integer) 12

18、APPEND 

APPEND key数值 # 往字符串后面追加内容

127.0.0.1:6379> set name1 value1
OK
127.0.0.1:6379> get name1
"value1"        # 字符串长度是6
127.0.0.1:6379> APPEND name1 ",hello"  # 给key-name1中的value追加内容
(integer) 12    # 追加后的字符串长度是12
127.0.0.1:6379> get name1
"value1,hello"   # value1字符串长度是6, ,hello字符串长度是6
127.0.0.1:6379> 

三、redis的列表List 

在 Redis 可以将 list 进行增加规则,实现做成一个栈(先进后出,列表的右端是堵塞的),先 set 的数值,最后 get 才能获取到。或者一个队列(先进先出,列表的左端是堵塞,但是右端是非堵塞的),先 set 的数值,最先 get 获取。或者是阻塞队列,将两边的左端右端都打开,从两边set 或者 get 获取

1、RPUSH

RPUSH 命令可以向 list 的右边(尾部)添加一个新的元素

127.0.0.1:6379> RPUSH list1 1
(integer) 1
127.0.0.1:6379> RPUSH list1 2
(integer) 2
127.0.0.1:6379> RPUSH list1 3
(integer) 3

可以多行的插入
127.0.0.1:6379> RPUSH list3 1 2 3 4
(integer) 4
127.0.0.1:6379> LRANGE list3 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> 

 2、LPUSH

LPUSH 命令可以向 list 的左边(头部)添加一个新的元素

127.0.0.1:6379> LPUSH list1 A
(integer) 4
127.0.0.1:6379> LPUSH list1 B
(integer) 5
127.0.0.1:6379> 

可以多行的插入
127.0.0.1:6379> LPUSH list2 1 2 3 4
(integer) 4
127.0.0.1:6379> LRANGE list2 0 -1
1) "4"
2) "3"
3) "2"
4) "1"

3、LLEN 

获取列表的长度

127.0.0.1:6379> LLEN list1
(integer) 5
127.0.0.1:6379> 

4、LRANGE 

最后 LRANGE 命令可以从 list 中取出一定范围的元素获取列表数据。没有RRANGE 

127.0.0.1:6379> LRANGE list1 0 -1   # 索引0 ~ -1
1) "B"
2) "A"
3) "1"
4) "2"
5) "3"
127.0.0.1:6379> 

127.0.0.1:6379> LRANGE list1 1 3   # 索引1 ~ 3
1) "A"
2) "1"
3) "2"
127.0.0.1:6379> LRANGE list1 2     # 必须是范围
(error) ERR wrong number of arguments for 'lrange' command
127.0.0.1:6379> LRANGE list1 2 2   # 索引2
1) "1"
127.0.0.1:6379> 

5、LPOP  RPOP

LPOP 从左侧删除第一个元素。
RPOP 从右侧删除第一个元素 
没有步长,不能指定删除那个具体元素,也不能范围删除

127.0.0.1:6379> LRANGE list1 0 -1
1) "B"
2) "A"
3) "1"
4) "2"
5) "3"
127.0.0.1:6379> RPOP list1 
"3"
127.0.0.1:6379> LRANGE list1 0 -1
1) "B"
2) "A"
3) "1"
4) "2"
127.0.0.1:6379> LPOP list1 
"B"
127.0.0.1:6379> LRANGE list1 0 -1
1) "A"
2) "1"
3) "2"
127.0.0.1:6379>  

127.0.0.1:6379> LPOP list1 1
(error) ERR wrong number of arguments for 'lpop' command
127.0.0.1:6379> LPOP list1 1 1
(error) ERR wrong number of arguments for 'lpop' command

三、Hash 哈希操作

Hash 看起来像一个‘hash’ 的样子,由键值对组成

redis 作为 mysql 的缓存,主要通过 hash 来实现。

具体如下:
1、比如mysql中有一个user信息表,会有uid(主键ID不会重复)、name字段、age字段、job字段
2、用户直接访问mysql :select * from user where uid=100 
3、存储到redis中:
(key名称)       vaule
user:100        name:zhang   age:28   job:it
4、将 user:100 作为 redis 中的 key ,将 name:zhang age:28 job:it 作为 redis 中的 vaule
5、get user:100 获得 name:zhang age:28 job:it 作为 redis ,就跟 select * from user where uid=100 是一样的效果

1、HMSET

HMSET: hash 类型插入多个数值

127.0.0.1:6379> HMSET user:100 name zhang age 28 job it  # user:100是key,代表mysql中的user表中ID唯一值这列中等于100的一样,value 是 name zhang age 28 job it 
OK
127.0.0.1:6379> 

2、HGET

HGET:一次只能取出单个值

127.0.0.1:6379> HMSET user:100 name zhang age 28 job it
OK
127.0.0.1:6379> HGET user:100 age   # 取出 key 等于 user:100,value 中 age 对应的数值
"28"
127.0.0.1:6379> HGET user:100 age name
(error) ERR wrong number of arguments for 'hget' command
127.0.0.1:6379> 

3、HMGET

HMGET: 一次取出多个值

127.0.0.1:6379> HMSET user:100 name zhang age 28 job it
OK
127.0.0.1:6379> HMGET user:100 age   # 取出 key 等于 user:100,value 中 age 对应的数值
1) "28"
127.0.0.1:6379> HMGET user:100 name job   # 取出 key 等于 user:100,value 中 age 和job 对应的数值
1) "zhang"
2) "it"

4、HGETALL

获取 key 中的所有的 value 信息

127.0.0.1:6379> HGETALL user:100
1) "name"
2) "zhang"
3) "age"
4) "28"
5) "job"
6) "it"
127.0.0.1:6379> 

四、集合类型

集合 是字符串的无序列操作,A 集合 跟 B集合的交集、差集、并集
使用:找到精确的匹配,A有的B也有的,给A推送的文件,可以给B推送(交集)

1、SADD 

SADD 集合名称  集合元素  #  创建集合 ,新的元素添加到集合中

127.0.0.1:6379> SADD set1 1 2 3 4 5
(integer) 5
127.0.0.1:6379> SADD set2 3 6 2 10
(integer) 4
127.0.0.1:6379> 

2、SMEMBERS 

查看集合中的内容,通过查看,集合是默认给排序的

127.0.0.1:6379> SMEMBERS set1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
127.0.0.1:6379> SMEMBERS set2
1) "2"
2) "3"
3) "6"
4) "10"
127.0.0.1:6379> 

3、注意事项

和 list 类型不同,集合并不允许出现重复的元素,所以如果插入一个已经存在的元素,是不进行操作,所以集合中不会出现相同的元素

127.0.0.1:6379> SMEMBERS set2
1) "2"
2) "3"
3) "6"
4) "10"
127.0.0.1:6379> SADD set2 4 6 9   # 6 元素已经存在,所以不会插入
(integer) 2                       # 说明插入两个,4 9 ,而 6 已经存在
127.0.0.1:6379> SMEMBERS set2 
1) "2"
2) "3"
3) "4"
4) "6"
5) "9"
6) "10"
127.0.0.1:6379> 

4、SREM

删除指定的数值

127.0.0.1:6379> SMEMBERS set2
1) "2"
2) "3"
3) "4"
4) "6"
5) "9"
6) "10"
127.0.0.1:6379> SREM set2 3 4 10
(integer) 3
127.0.0.1:6379> SMEMBERS set2
1) "2"
2) "6"
3) "9"
127.0.0.1:6379> 

5、SDIFF

集合与集合之间的对比,有哪些不同,以第一个集合为准,第一个有的,第二个没有的

127.0.0.1:6379> SMEMBERS set1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "9"
127.0.0.1:6379> SMEMBERS set2
1) "2"
2) "6"
3) "9"
127.0.0.1:6379> SDIFF set1 set2
1) "1"
2) "3"
3) "4"
4) "5"
# 拿 set1 对比 set2, set1有1而set2没有1,所以1是不同的
# 拿 set1 对比 set2, set1有2而set2有2,所以2不是不同,不要
# 拿 set1 对比 set2, set1有3而set2没有3,所以3是不同的
# 拿 set1 对比 set2, set1有4而set2没有4,所以4是不同的
# 拿 set1 对比 set2, set1有5而set2没有5,所以5是不同的
# 拿 set1 对比 set2, set1有9而set2有9,所以9不是不同,不要

127.0.0.1:6379> SDIFF set2 set1
1) "6"
127.0.0.1:6379> 
# 拿 set2 对比 set1, set2有2而set1有2,所以2不是不同,不要
# 拿 set2 对比 set1, set2有6而set1没有6,所以6不是不同
# 拿 set2 对比 set1, set2有9而set1有8,所以9不是不同,不要

6、SINTER 

取交集

127.0.0.1:6379> SMEMBERS set1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "9"
127.0.0.1:6379> SMEMBERS set2
1) "2"
2) "6"
3) "9"
127.0.0.1:6379> SINTER set1 set2
1) "2"
2) "9"
127.0.0.1:6379> SINTER set2 set1
1) "2"
2) "9"

7、SUNION

并集

127.0.0.1:6379> SUNION set1 set2
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "9"
127.0.0.1:6379> SUNION set2 set1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "9"
127.0.0.1:6379> 

 七、Redis 禁用危险命令

1、Redis 危险命令

  • keys * :虽然其模糊匹配功能使用非常方便也很强大,在小数据量情况下使用没什么问题,数据量大会导致 Redis 锁住及 CPU 飙升,在生产环境建议禁用或者重命名!
  • flushdb :删除 Redis 中当前所在数据库中的所有记录,并且此命令从不会执行失败
  • flushall :删除 Redis 中所有数据库中的所有记录,不只是当前所在数据库,并且此命令从不会执行失败。
  • config :客户端可修改 Redis 配置。

2、禁用 Reids 命令

# 进入 redis.conf 默认配置文件,找到 SECURITY 区域;添加如下配置
 
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""
rename-command CONFIG ""

 3、重命名(未尝试)

# 如果想要保留命令,但是不能轻易使用,可以重命名命令来设定,设置随机字符代替:
# 注意:重启服务器后,则需要用新命令来执行操作,否则服务器会报错 unknown command。
#      对于FLUSHALL命令,需要设置配置文件中appendonly no,否则服务器无法启动。
 
rename-command FLUSHALL "dcec4362797e4684b4aaef3c467cbd54"
rename-command FLUSHDB "48eab610b9fa474fbff2e2f8288e99b1"
rename-command KEYS "1bd08134aecf48aeb2b418db034e6414"
rename-command CONFIG "0095e05639824bf5b9912055bc243c45"

八、验证 set 执行的时间

# 写入
[root@86-5-master ~]# cat redis.sh 
#! /bin/bash

for i in {1..100000}
do 
  redis-cli -h 127.0.0.1 set k_{$i} v_{$i}
done

[root@86-5-master ~]# time sh redis.sh   # time模块查看脚本执行时间

real	0m28.747s
user	0m4.342s
sys	0m19.051s

# 读取
[root@86-5-master ~]# cat redis.sh 
#! /bin/bash

for i in {1..100000}
do 
  redis-cli -h 127.0.0.1 get k_{$i}
done

[root@86-5-master ~]# time sh redis.sh   # time模块查看脚本执行时间

real	0m28.747s
user	0m4.342s
sys	0m19.051s

九、redis中的命令

# 查看redis服务信息,比如版本redis_version:5.0.4
info server

# 查看redis的cpu信息
info cpu

# 查看redis占用内存的信息
# 比如used_mem_human:1.87M,表示redis数据占用1.87M,used_mem_rss:7.91M表示系统占用总大小。
info memory


 

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值