既然要学习 Redis,那么就先了解一下什么是 NoSQL 吧。

NoSQL 的全称是 Not Only SQL,不仅是 SQL。

什么是 NoSQL

NoSQL 泛指非关系型数据库,伴随着 web2.0 互联网的诞生。传统的关系型数据库早已很难对付 web2.0 时代,尤其是超大规模的高并发舍弃,暴露出来很多难以克服的问题,NoSQL 在当今大数据环境下发展的十分迅速,Redis 是发展最快的。

很多的数据类型用户的个人信息,社交网络,地理位盾。这些数据类型的存储不需要一个固定的格式!不需要多余的操作就可以横向扩展的!

比如 Java 中的 Map<String, Object> 使用是键值对的方式来控制的,它是 NoSQL 的一种表现形式。

特点

  1. 方便扩展
    1. 数据之间没有关系
  2. 大数据量,高性能
    1. 一秒写 8 万次,读取 11 万,NoSQL 的缓存记录级,是一种细粒度的缓存,性能会比较高。
  3. 数据类型多样化
    1. 不需要事先设计数据库,随取随用,如果是数据量十分大的表,很多人就无法设计了!
  4. 传统 RDBMS 和 Nosql
    1. 传统的 RDBMS
      1. 结构化组织
      2. SQL
      3. 数据和关系都在单独的表中
      4. DDL、DML、DCL、DQL
      5. 严格的一致性
      6. 基础的事务
      7. ……
    2. Nosql
      1. 没有固定的查询语言
      2. 键值对存储,列存储,文档存储,图形数据库(社交关系)
      3. 最终一致性,
      4. CAP 定理和 BASE (异地多活)初级架构师!(狂神理念:只要学不死,就往死里学!)
      5. 高性能,高可用,高可扩
      6. ……

目前,NoSQL 和 RDBMS 结合起来使用,使性能达到最佳。

NoSQL 的四大分类

KV键值对:

  • 新浪:Redis
  • 美团:Redis +Tair
  • 阿里、百度:Redis + memecache

文档型数据库 ( bson 格式和 json 一样)∶

  • MongoDB (一般必须要掌握)
    • MongoDB 是一个基于分布式文件存储的数据库,C++编写,主要用来处理大量的文档!
    • MongoDB 是一个介于关系型数据库和非关系型数据中中间的产品!MongoDB是非关系型数据库中功能最丰富,最像关系型数据库的!
  • CouchDB

列存储数据库

  • HBase
  • 分布式文件系统

图关系数据库

图关系数据库存的是关系,而不是图形。

img

Redis 是什么

Redis ( Remote Dictionary Server ),即远程字典服务!

是一个开源的使用 ANSl C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。

Redis 能做什么

  1. 内存存储、持久化(rdb、aof)
  2. 效率高,可以用于高速缓存
  3. 发布订阅系统
  4. 地图信息分析
  5. 计时器、计数器

安装 Redis

Redis 的安装有 Windows 版和 Linux 版,Windows 版解压直接运行 redis-server 即可。Linux 版只提供源代码,需要自己通过编译源代码的方式来安装。

我在学习的时候用的是 Linux 版,安装时候有几个步骤。

1、使用 wget 命令去下载,如果提示 -bash: wget: command not found ,则需要安装一下 wget,然后再下载。

31  yum -y install wget
33  wget https://download.redis.io/releases/redis-6.2.5.tar.gz

2、解压,进入目录

tar zxvf redis-6.2.5.tar.gz 
cd redis-6.2.5

3、安装一下 c++ 的编译器,如果你有,就不用装。

yum -y install gcc-c++

4、编译并安装

make MALLOC=libc
make install

这样,Redis 就安装完成了。

启动 Redis

Redis 的默认的安装位置是在 /usr/local/bin ,里面有如下信息。

[root@localhost bin]# ls
redis-benchmark  redis-check-aof  redis-check-rdb  redis-cli  redis-sentinel  redis-server

Redis 的配置文件,默认是保存在解压文件中。建议将配置文件复制到上面提到的路径当中。

由于 Redis 默认不是以后台运行的,所以要在配置文件中找到以下属性并配置成 yes。

################################# GENERAL #####################################

# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
# When Redis is supervised by upstart or systemd, this parameter has no impact.
daemonize yes

然后先运行服务端,再运行客户端,输入 ping 命令看看能不能联通,如果返回 PONG,说明连接成功了。

[root@localhost bin]# ./redis-server redis_conf/redis.conf 
[root@localhost bin]# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>

查看正在运行的 Redis 进程

[root@localhost ~]# ps -ef | grep redis
root       1372      1  0 16:49 ?        00:00:00 ./redis-server 127.0.0.1:6379
root       1376   1299  0 16:49 pts/0    00:00:00 redis-cli
root       1400   1382  0 16:52 pts/1    00:00:00 grep --color=auto redis

小试一下

试用 set 和 get 命令,保存一些信息并获取。

127.0.0.1:6379> set name xiaohehe
OK
127.0.0.1:6379> get name
"xiaohehe"

试用 redis-benchmark 命令来测试 redis 的单机性能,redis 的性能会受到服务器的制约,来感受一下速度。

[root@localhost ~]# redis-benchmark -h localhost -p 6379 -c 100 -n 100000

比如,我们看一下 LPUSH 的处理请求。

====== LPUSH ======                                                   
  100000 requests completed in 3.43 seconds
  100 parallel clients
  3 bytes payload
  keep alive: 1
  host configuration "save": 3600 1 300 100 60 10000
  host configuration "appendonly": no
  multi-thread: no

Latency by percentile distribution:
0.000% <= 0.991 milliseconds (cumulative count 2)
50.000% <= 2.287 milliseconds (cumulative count 50170)
75.000% <= 2.895 milliseconds (cumulative count 75016)
87.500% <= 3.471 milliseconds (cumulative count 87608)
93.750% <= 3.951 milliseconds (cumulative count 93756)
96.875% <= 4.351 milliseconds (cumulative count 96879)
98.438% <= 4.695 milliseconds (cumulative count 98458)
99.219% <= 5.031 milliseconds (cumulative count 99224)
99.609% <= 5.399 milliseconds (cumulative count 99610)
99.805% <= 5.847 milliseconds (cumulative count 99805)
99.902% <= 6.303 milliseconds (cumulative count 99903)
99.951% <= 10.199 milliseconds (cumulative count 99952)
99.976% <= 10.535 milliseconds (cumulative count 99976)
99.988% <= 10.703 milliseconds (cumulative count 99988)
99.994% <= 10.791 milliseconds (cumulative count 99994)
99.997% <= 10.839 milliseconds (cumulative count 99997)
99.998% <= 10.871 milliseconds (cumulative count 99999)
99.999% <= 10.911 milliseconds (cumulative count 100000)
100.000% <= 10.911 milliseconds (cumulative count 100000)

测试 LPUSH 时,在 请求次数为 100000 ,每次写入 3 个字节的数据,100个客户端同时并发的情况下,花费了 10.9 ms,如果不是在虚拟机也许会更快。

Redis 基础知识和基本命令

Redis 默认有 16 个数据库,可以在配置文件中查看并修改数据库个数,默认使用的数据库是第 0 个。

# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT <dbid> where
# dbid is a number between 0 and 'databases'-1
databases 16

select 命令是切换数据库。

127.0.0.1:6379> select 4 # 切换到4号数据库
OK
127.0.0.1:6379[4]>

dbsize 查看数据库大小,每一组键值对占用一个单位。

127.0.0.1:6379[4]> set name xiaohehe
OK
127.0.0.1:6379[4]> get name
"xiaohehe"
127.0.0.1:6379[4]> dbsize
(integer) 1

查看数据库中的键

127.0.0.1:6379[4]> keys *
1) "name"
127.0.0.1:6379[4]>

flushdb 清空当前数据库

127.0.0.1:6379[4]> flushdb
OK
127.0.0.1:6379[4]> dbsize
(integer) 0

flushall 清空全部数据库

127.0.0.1:6379[4]> flushall
OK
127.0.0.1:6379[4]> select 0
OK
127.0.0.1:6379> DBSIZE
(integer) 0

exists 判断当前的 key 是否存在

127.0.0.1:6379> exists name
(integer) 0

move 移除当前的 key 到其它数据库中

127.0.0.1:6379> set name2 xiaohehe
OK
127.0.0.1:6379> move name2 2
(integer) 1
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> get name2
"xiaohehe"

expire 设置 key 的过期时间,单位是秒

127.0.0.1:6379[2]> expire name2 10
(integer) 1

ttl 查看 key 的剩余时间,单位是秒,-1 为永久,-2 为不存在。

127.0.0.1:6379> ttl name2
(integer) 6
127.0.0.1:6379> ttl name2
(integer) 3
127.0.0.1:6379> ttl name2
(integer) 1
127.0.0.1:6379> ttl name2
(integer) 0
127.0.0.1:6379> ttl name2
(integer) -2

type 查看 key 中所保存的值的类型。

127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> type age
string

Redis 是单线程的

为什么?

明白 Redis 是很快的,因为 Redis 是基于内存操作,CPU 并不是 Redis 性能瓶颈,真正的 Redis 的性能瓶颈是在机器的内存和网络带宽,既然可以使用单线程来实现,就使用单线程了。

QPS(Query Per Second),QPS 其实是衡量吞吐量(Throughput)的一个常用指标,就是说服务器在一秒的时间内处理了多少个请求 —— 我们通常是指 HTTP 请求,显然数字越大代表服务器的负荷越高、处理能力越强。作为参考,一个有着简单业务逻辑(包括数据库访问)的程序在单核心运行时可以提供 50 - 100 左右的 QPS,即每秒可以处理 50 - 100 个请求。

Redis 是 C 语言写的,官方提供的数据为 100000+ 的 QPS,完全不比同样是使用 key-value 的 Memecache 差。

Redis 为什么很快

误区1∶高性能的服务器一定是多线程的?

误区2∶多线程一定比单线程效率高!

Redis 是将所有的数据全部放在内存中的,所以说使用单线程去操作效率就是最高的,由于多线程涉及到上下文切换,这对于内存系统来说就是浪费时间,如果没有上下文切换效率就是最高的!多次读写都是在一个 CPU 上的,在内存情况这个就是最佳的方案!

命令查询

http://www.redis.cn/commands.html