对于Redis,之前和很多人一样,使用它就是因为他是最流行的缓存方案,大部分就是简单的字符串的key-value结合get/set操作,设置一个超时时间。最近花了点时间深入的研究了一下原理,发现Redis确实是一个从实用出发的,设计非常精巧的系统,这也就是5,6万多行代码的系统能这么流行的原因。
公司最近做了一个内部门户,发发新闻、通知和公告。这种非业务系统正好可以使用redis非常轻巧的解决问题。下面我从需求开始,详细说明使用SpingBoot+Redis实现这个系统的具体步骤,后端代码放在github上,大家可以参考阅读https://github.com/chilexun/redis-blog。
需求
先从需求出发,门户的功能比较简单,1)可以发新闻、公告和通知,文章可置顶 2)用户可以留言和点赞 3)可以对用户留言点赞 4)支持阅读数、留言数和点赞数等统计功能 5)支持搜索功能 6)支持通讯录用户登录等功能。
抛开通讯录,搜索功能(使用ElasticSearch实现),其实就是一个完整的个人博客系统。
框架
需求已明确,做下简单的技术选型,大概的技术架构如下:
数据持久化使用Redis,使用sentinel模式做主备高可用。框架使用流行的springboot,因为要支持APP,手机浏览器和PC访问,所以做了前后端的分离。搜索选了ElasticSearch。
说下技术选择的出发点:
1)为什么持久层使用redis而不是MySQL?
主要是因为业务简单,就是简单的增删改查而且没有复杂的过滤统计,读多写少,使用redis AOF做数据落盘基本不会丢数据,实在不需要动用关系型数据库。第二是数据量不大,一年的数据加起来不到1G,哪怕系统用10年,单机内存也足够了。第三是速度,这个就不用讲了,因为使用MySQL为了体验,也要把页面做下缓存,还不如全部放缓存里,不但提升速度,还降低复杂度。
2)搜索为什么不直接用redis?
虽然是内部的项目,也是有时间限制的,用redis实现搜索功能,数据结构设计方面还是要投入不少时间的,所以就先用ES搞了。
3)为什么用SpringBoot不用更轻量级的,比如JFinal?
纯粹为了学习springboot,哈哈。当然Spring对Redis的封装已经很好了,所以也省了不少事。
4)为什么用哨兵而不用redis cluster?
原因很简单,数据量不大,并发不高。容灾和高可用的要求不高。
下面开始搭建环境。
Redis安装和sentinel配置
安装
我的环境是CentOS7,首先下载最新版的Redis,https://redis.io/download,我下载的是4.0.10
$ cd /opt
$ wget http://download.redis.io/releases/redis-4.0.10.tar.gz
$ tar xzf redis-4.0.10.tar.gz
$ cd redis-4.0.10
$ make
安装完之后一般会提示,做一个覆盖性测试,照做就好了,只要安装过程没问题,肯定可以全部通过。
编译好后的二进制文件会和源代码在一个目录,为了方面访问,我们建一个文件连接,放到/usr/bin目录下
$ cd /usr/bin
$ ln -s /opt/redis-4.0.10/src/redis-cli redis-cli
$ ln -s /opt/redis-4.0.10/src/redis-sentinel redis-sentinel
$ ln -s /opt/redis-4.0.10/src/redis-server redis-server
配置
下面是把master,slave和sentinel安装到一台服务器上,所以端口号要做区分。下面所有这些只是推荐配置,为了保证数据的持久化和恢复的速度,所以打开了AOF。也可以使用BGSAVE保存,将文件注释掉的配置打开,AOF相关的配置注释掉就可以了。
首先为master,slave和sentinel创建3个配置文件,放在不同的目录下。配置文件的内容如下:
Redis Master配置(/home/admin/data/redis/6379/redis.conf)
port 6379 # 端口号
protected-mode no #关闭保护模式,允许通过网络远程连接
redisrequirepass Blog2018dev$ #访问密码
logfile /home/admin/data/redis/6379/stdout.log #日志存储路径
databases 1 # Redis 数据库个数,推荐只用1个
#save 60 1 # 每60秒钟超过1次数据变更,则执行BGSAVE
#save 30 10 # 每30秒钟超过10次数据变更,则执行BGSAVE
#dbfilename dump.rdb # BGSAVE dump数据保存的文件名
dir /home/admin/data/redis/6379/ #RDB文件保存的路径
appendonly yes #是否打开AOF
appendfsync everysec #AOF每秒钟执行一次fsync,操作系统将做一次强制将数据刷新到磁盘的动作
auto-aof-rewrite-percentage 100 # AOF当新写入的数据量超过文件大小一倍后做一次重写,压缩文件体积
auto-aof-rewrite-min-size 64mb #AOF文件超过64M才会开启重写
Redis Slave 配置 ( /home/admin/data/redis/6389/redis.conf)
port 6389
protected-mode no
logfile "/home/admin/data/redis/6389/stdout.log"
databases 1
#save 60 1
#dbfilename "dump.rdb"
dir "/home/admin/data/redis/6389"
slaveof 10.128.105.104 6379 # 设置slave
masterauth "Blog2018dev$" # master的密码
slave-read-only yes # 将slave设置成只读
requirepass "Blog2018dev$"
appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
Sentinel 配置 ( /home/admin/data/redis/26379/sentinel.conf)
port 26379
protected-mode no
dir "/tmp" #程序运行的目录
logfile "/home/admin/data/redis/sentinel-26379/stdout.log"
sentinel monitor master001 10.128.105.104 6379 1 # sentinel monitor 参数,master001:主备组的名称,master的ip和端口,切换时需要几个sentinel同意,现在只有一个,如果启动3个sentinel则设置成2
sentinel auth-pass master001 "Blog2018dev$" # master的密码
启动
Master:
$ cd /home/admin/data/redis/6379/
$ redis-server redis.conf
Slave:
$ cd /home/admin/data/redis/6389/
$ redis-server redis.conf
Sentinel:
$ cd /home/admin/data/redis/26379/
$ redis-sentinel sentinel.conf
启动好之后,就可以用客户端连上看是否正常,推荐一个好用的Redis Windows客户端,Redis Desktop Manager。
到现在redis的配置已经结束了,下一节我们来讲SpringBoot + Redis环境构建