原创作者,公众号【程序员读书】,欢迎关注公众号,转载文章请注明出处哦。
影响服务器性能的因素有很多,比如CPU、内存、硬盘等硬件设备条件的限制,也有服务器整体架构、程序员的代码质量、使用的算法和数据结构优劣等方方面面的因素。
不过个人感觉对服务器性能影响最大,应该是数据库,服务器在面对高并发请求时,性能瓶颈往往出现在数据库方面,因为数据库扛不了那么高的并发数,而使用数据库集群往往也意味着较高的硬件和软件成本,因此,如果在代码层与数据库之间再加一层缓存,可以有效缓解数据库的压力,大大提升服务器的性能。
而提到缓存,我们最先想到的是什么,是Redis
,或许这就是Redis
给我们的第一印象,虽然这样理解Redis并不完全正确,因为Redis
所能做,并不仅仅于此,下面一起探究一下吧。
什么是Redis
Redis
是一名叫Salvatore Sanfilippo的人在2009年使用ANSI C
编写的开源的内存数据结构存储系统,Redis的作者开发Redis很大一部分原因,也是因为数据库无法满足他的需求。
当然啦,我们可以把Redis简单地理解为内存数据库(NoSQL)或者Key-Value键值对服务器。
Redis
提供了多种数据结构和不同编程语言的客户端API
,另外,也提供了持久化、主从复制、事务等多种功能和特性,就像一把瑞士军刀一般,是服务器开发中的一把利器。

虽然Redis
提供了非常强大的功能,但Redis
的代码却非常简单,其最初的版本只有23000行代码,而最近的某一个版本代码也只有50000多行而已,因此,感兴趣的人可以研究一下Redis
源码。
Redis的特性
下面列出一些Redis
的特性,让我们对Redis
有个比较全面的了解,其实,从这些特性中,也可以看出Redis
的强大。
速度快
Redis
的响应速度非常快,之所以这么快,最大的原因是Redis
对数据的操作都是在内存中进行的,我们从下面的存储器层次结构图便可以看到,内存的读写速度比硬盘(无论是固态还是机械硬盘)都在快很多,因此Redis自然就非常快速。

持久化
前面我们说Redis
将数据放在内存中,,但Redis
也提供了持久化机制,这样可以将用户存储到内存中的数据,定时持久化到硬盘等存储设备中,保证服务器断电重启时,数据不会消失,Redis
支持RDB
和AOF
两种持久化机制,有机会,我们在以后的文章中讲讲这两种机制的区别。
多种数据类型
Redis
支持多种类型的数据结构,这也是Redis
与Memcached
的区别之一,Memcached
只支持String
类型,而Redis
除了String
、Hash
、List
、Set
、Sort Set
这些基本的数据类型外,还有BitMaps(位图)
、HyperLogLog(超小内存唯一值计数)
、GEO(地理信息定位)
等高级的数据类型。
支持多种编程语言客户端
Redis为大多数编程语言都提供了客户端API,这些API有些是官方提供的,有些则来自开源社区的贡献,所以不管你使用什么语言来开发服务器应用,都可以很方便连接Redis。
下面是Redis官网上列出所有编程语言API列表的地址
# redis支持的客户端列表
https://redis.io/clients
发布订阅
Redis
支持订阅与发布的功能,因此可以使用Redis
来实现一个简单消息队列,一端作为发布者把消息发布到Redis
,而另一端作为消费者,处理来自Redis
的消息。
Lua脚本
Redis
在V2.6u新增了脚本功能,允许客户端使用Lua语言编写脚本传到Redis
中执行,这样做的好处是:减少网络开销原子操作和脚本复用,关于Redis中如何使用Lua脚本,有空再说。
事务
Redis支持事务,当我们需要执行多条命令时,保证多条命令执行原子性,因为在事务中,多条命令的执行,要么都成功,要么都失败,当然,要执行多个命令,使用Lua脚本也许更加方便。
主从复制
Redis支持主从复制功能,即主服务器的数据,可以同步到多台从服务器上,所以主从复制实际是为Redis的高可用和分布式提供了基础。

高可用分布式
Redis也支持高可用和分布式,实际主从复制只是实际高可用的基础,但要通过主从复制实现高可用是不太可能的,Redis的高可用是通过Redis Sentinel(哨兵)
来实现的,Redis Sentinel是在V2.8增加的功能,而分布式则需要Redis cluster
功能的支持,Redis_cluster
是在v3.0之后增加的功能。
单线程
Redis
是单线程的,这里所说的单线程,指其在Redis作为服务器在接收客户端网络请求时采用是单线程,所以在同一时刻,Redis无法同时处理两个请求,只有一个请求处理完成再处理下一个请求,不过Redis在实现某个功能时,还是使用的多线程的,比如将数据持久化到硬件,就是开启另一个线程来实现的。
安装并启动Redis
Redis
的安装非常简单,这里介绍两种安装方式,一种是从Redis
官网上下载源码,然后编译安装,另外一种更加方便,直接从Docker Hub
上拉取Redis
的docker
镜像。
下面介绍的是在Linux系统上安装Redis的过程。
使用源码编译安装
# 下载redis源码安装包
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
# 解压缩
tar -zxvf redis-5.0.5.tar.gz
# 进入redis源码目录
cd redis-5.0.5
# 编译 & 安装
make && make install
使用Docker镜像安装并启动Redis
Redis提供了docker镜像,因此我们可以很方便拉取并运行Redis镜像,不过,前提是你的服务器上有安装docker
。
# 从Docker Hub上拉取官方镜像,redis:latest
docker pull redis
# 从镜像中启动一个容器
docker run --name my_redis -p 6379:6379 -d redis
这里要说明一点,就是Redis作者并没有开发Redis的Windows版本,可能Redis的作者觉得安装Windows系统的服务器不适合运行Redis,又或者什么原因,不过微软还是提供了Redis的Windows版本。
# redis的windows版本
https://github.com/microsoftarchive/redis/releases
启动Redis的几种方式
不带参数,使用默认配置启动服务器
# 使用默认配置启动
redis-server
指定命令行参数启动服务器
# 使用命令参数配置启动
redis-server --port 6380
使用配置文件启动服务器
# 使用配置文件启动
redis-server ~/redis-5.0.5/redis.conf
连接Redis
在使用前面介绍的几种方式启动Redis服务器后,我们就可以使用Redis客户端连接服务器,向服务器写入或读取数据,前面我们说过Redis支持大多数编程语言,因此大大家可以根据自己的情况选择不同的API。
使用命令行客户端连接Redis
在安装好Redis之后,就可以使用Redis安装包中自带的客户端redis-cli
,这是一个命令行客户端,其使用示例如下:
# 直接使用,不带参数,会连接本地服务器
redis-cli
# 指定地址和端口号
redis-cli -h 服务器地址 -p 端口号
使用代码连接Redis服务器
在这里演示使用golang
的开发的redigo/redis
包连接Redis
服务器。
# 获取go语言的某个redis客户端库
go get github.com/gomodule/redigo/redis
下面是使用redigo/redis
库连接Redis的简单代码示例:
package main
import (
"fmt"
"github.com/gomodule/redigo/redis"
)
var redisCon redis.Conn
func main() {
var err error
redisCon ,err = redis.Dial("tcp","localhost:6379")
if err != nil{
panic(err)
}
defer redisCon.Close()
rs,err := redisCon.Do("set","test_key","test_value")
if err != nil{
panic(err)
}
fmt.Println(rs)
}
上面的代码可能比较简单,有机会我们详细了解如何使用Golang更好地连接和操作Redis。
应用场景
下面列出一些Redis
的使用场景,我们也可以根据自己的需要,灵活使用Redis
来达到提升服务器性能的目的。
缓存系统
Redis
最常被使用的场景就是用于数据缓存,由于其基于内存的数据快速读写操作,响应速度非常快,可以用于缓存一些热点数据或者不怎么变化的数据,这样,当用户请求这些数据时,直接从Redis
快速读取,避免频繁的数据库读写,提升服务器的数据吞吐量及速度。
排行榜
Redis
的sort set
数据类型非常适合做排榜行功能,比如【掘金】的【推荐作者榜】其实实现的原理应该就是将计算后的作者排行权重放在Redis
的sort set
中来实现的,因此Redis
在实现这类功能真的是非常方便简单。

实现社区功能
Redis的功能与一些社区功能有着天然的契合性,使用Redis所支持的数据结构,可以容易存储社区功能中的如关注数,粉丝数,关注列表,粉丝列表,共同共注等数据,比如关注数与粉丝数可以用计数器,关注列表和粉丝列表可以使用set
o类型来存储。
计数器
Redis
内置的incr
命令可以很方便地单线程下进行计数,而且这种操作是原子性,不用担心某个时刻有两个请求对同一个键值进行计数,这种计数器功能在某些场景下非常实用,比如掘金的文章,阅读数、评论数、点赞数可以使用Redis的计数功能来实现,想想,如果这些数据直接写入数据库,那么每次有人点赞、阅读、评论都需要对数据库进行操作,估计数据库会挂掉,而使用Redis计数功能,则可以快速轻松完成这种功能的实现。

消息队列
Redis
支持发布订阅功能,因此可以把Redis
当作一个简单的消息队列,当我们有一些业务需要使用消息队列时,可以考虑使用Redis
来实现,当然,成熟的消息队列中间件系统有很多,如Kafka
,RabbitMQ
,RocketMQ
,ActiveMQ
,然后使用这些可能需要额外的软硬件成本及学习成本,因此可以使用Redis
的消息队功能来替代。

实时系统
对于一些需要实时处理的数据,也可以直接写入Redis
中,再由其他系统进行处理,这其实也是利用了Redis
发布订阅的功能,来达到数据实时处理的目的,比如一些垃圾邮箱处理系统等。
小结
在这篇文章中,我们简单地谈了一下Redis
是什么,可以做什么,并了解其强大的特性和功能,通过演示如何安装、启动和连接Redis
,也让我们知道如何使用Redis
,当然啦,想要更好地了解和使用Redis
,还需要更加深入地学习,下面有机会,我们继续这方面的学习。
你的关注,是我写作路上最大的鼓励!
