Redis,提高服务器性能的一把瑞士军刀

原创做者,公众号【程序员读书】,欢迎关注公众号,转载文章请注明出处哦。git

影响服务器性能的因素有不少,好比CPU、内存、硬盘等硬件设备条件的限制,也有服务器总体架构、程序员的代码质量、使用的算法和数据结构优劣等方方面面的因素。程序员

不过我的感受对服务器性能影响最大,应该是数据库,服务器在面对高并发请求时,性能瓶颈每每出如今数据库方面,由于数据库扛不了那么高的并发数,而使用数据库集群每每也意味着较高的硬件和软件成本,所以,若是在代码层与数据库之间再加一层缓存,能够有效缓解数据库的压力,大大提高服务器的性能。github

而提到缓存,咱们最早想到的是什么,是Redis,或许这就是Redis给咱们的第一印象,虽然这样理解Redis并不彻底正确,由于Redis所能作,并不只仅于此,下面一块儿探究一下吧。golang

什么是Redis

Redis是一名叫Salvatore Sanfilippo的人在2009年使用ANSI C编写的开源的内存数据结构存储系统,Redis的做者开发Redis很大一部分缘由,也是由于数据库没法知足他的需求。redis

固然啦,咱们能够把Redis简单地理解为内存数据库(NoSQL)或者Key-Value键值对服务器算法

Redis提供了多种数据结构和不一样编程语言的客户端API,另外,也提供了持久化、主从复制、事务等多种功能和特性,就像一把瑞士军刀通常,是服务器开发中的一把利器。docker

Redis就像这样一把瑞士军刀

虽然Redis提供了很是强大的功能,但Redis的代码却很是简单,其最初的版本只有23000行代码,而最近的某一个版本代码也只有50000多行而已,所以,感兴趣的人能够研究一下Redis源码。数据库

Redis的特性

下面列出一些Redis的特性,让咱们对Redis有个比较全面的了解,其实,从这些特性中,也能够看出Redis的强大。编程

速度快

Redis的响应速度很是快,之因此这么快,最大的缘由是Redis对数据的操做都是在内存中进行的,咱们从下面的存储器层次结构图即可以看到,内存的读写速度比硬盘(不管是固态仍是机械硬盘)都在快不少,所以Redis天然就很是快速。windows

存储器层次结构图 【摘自《深刻理解计算机系统》】

持久化

前面咱们说Redis将数据放在内存中,,但Redis也提供了持久化机制,这样能够将用户存储到内存中的数据,定时持久化到硬盘等存储设备中,保证服务器断电重启时,数据不会消失,Redis支持RDBAOF两种持久化机制,有机会,咱们在之后的文章中讲讲这两种机制的区别。

多种数据类型

Redis支持多种类型的数据结构,这也是RedisMemcached的区别之一,Memcached只支持String类型,而Redis除了StringHashListSetSort 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上拉取Redisdocker镜像。

下面介绍的是在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快速读取,避免频繁的数据库读写,提高服务器的数据吞吐量及速度。

排行榜

Redissort set数据类型很是适合作排榜行功能,好比【掘金】的【推荐做者榜】其实实现的原理应该就是将计算后的做者排行权重放在Redissort set中来实现的,所以Redis在实现这类功能真的是很是方便简单。

掘金推荐做者榜

实现社区功能

Redis的功能与一些社区功能有着自然的契合性,使用Redis所支持的数据结构,能够容易存储社区功能中的如关注数,粉丝数,关注列表,粉丝列表,共同共注等数据,好比关注数与粉丝数能够用计数器,关注列表和粉丝列表可使用seto类型来存储。

计数器

Redis内置的incr命令能够很方便地单线程下进行计数,并且这种操做是原子性,不用担忧某个时刻有两个请求对同一个键值进行计数,这种计数器功能在某些场景下很是实用,好比掘金的文章,阅读数、评论数、点赞数可使用Redis的计数功能来实现,想一想,若是这些数据直接写入数据库,那么每次有人点赞、阅读、评论都须要对数据库进行操做,估计数据库会挂掉,而使用Redis计数功能,则能够快速轻松完成这种功能的实现。

消息队列

Redis支持发布订阅功能,所以能够把Redis看成一个简单的消息队列,当咱们有一些业务须要使用消息队列时,能够考虑使用Redis来实现,固然,成熟的消息队列中间件系统有不少,如KafkaRabbitMQRocketMQActiveMQ,而后使用这些可能须要额外的软硬件成本及学习成本,所以可使用Redis的消息队功能来替代。

Redis消息队列示意图

实时系统

对于一些须要实时处理的数据,也能够直接写入Redis中,再由其余系统进行处理,这其实也是利用了Redis发布订阅的功能,来达到数据实时处理的目的,好比一些垃圾邮箱处理系统等。

小结

在这篇文章中,咱们简单地谈了一下Redis是什么,能够作什么,并了解其强大的特性和功能,经过演示如何安装、启动和链接Redis,也让咱们知道如何使用Redis,固然啦,想要更好地了解和使用Redis,还须要更加深刻地学习,下面有机会,咱们继续这方面的学习。


你的关注,是我写做路上最大的鼓励!

相关文章
相关标签/搜索