redis简介:
1:内存数据库,同时也能够保存数据到磁盘;
2:比其他的内存数据库有着更多的数据类型:
列表,集合,排序集合,哈希表等;
3:主从结构:数据可以备份到从服务器;
4: Redis数据操作速度快;
5:所有的操作都是原子操作;
下载安装redis服务
redis和mysql一样,也是需要下载安装redis服务的,基本安装如下:
1.官网下载redis: https://redis.io , 进入官网点击download
2.Redis 在 Windows 上不受官方支持。但是,可以按照以下说明在 Windows 上安装 Redis 进行开发,要在 Windows 上安装 Redis,您首先需要启用WSL2(适用于 Linux 的 Windows 子系统)。WSL2 允许您在 Windows 上本地运行 Linux 二进制文件。要使此方法起作用,您需要运行 Windows 10 版本 2004 及更高版本或 Windows 11,相关教程:https://redis.io/docs/getting-started/installation/ ,这里我不采用此方式进行安装,我去到github上下载项目安装,github仓库地址: https://github.com/MSOpenTech/redis或https://github.com/microsoftarchive/redis
3.redis只提供了win64位版本,如果你的电脑是32位的你可以下载源码build成32位的,源码地址:https://github.com/microsoftarchive/redis,这里可以百度redis在win32位安装步骤。
4.我电脑和服务器是64位的,这里我直接下载别人build好的文件进行安装,点击如下红色箭头所指进入到文件下载页面:
5.进入release page后有两种选择,这里我选msi结尾配置好的安装包点击下载,将下载好的程序放到某个文件夹并以程序名新建一个文件夹(当然这里可以不用新建文件夹,我是方便打理,将所有服务软件装在同一个盘下的某个根文件夹下),之后双击箭头所指安装程序:
6.同意协议并继续:
7.这里我更改安装目录并将path环境变量自动配置,之后点击next,如:
8.配置端口号和配置防火墙,这里我采用默认,当然上线项目可以更改默认端口号,如:
9.默认是不勾选内存限制的,这里我勾选了内存限制,并限制最大存100Mb数据,当然可以不勾选,后面可以在配置文件自行配置:
10.最后点击install进行安装,如:
11.此时电脑可能会弹框提示点击(是允许)即可,最后点击finish完成安装
12.安装完成后我一般会将安装程序删除,保留服务程序即可,如:
13.进入到安装包根目录下,打开箭头所指doc文档可看到对各个文件的基本介绍,如:
14.还需要了解下面三个文件,其中redis.windows.conf文件是可编辑的,是对redis服务的配置信息,里面可以设置端口、内存大小限制等,如
配置文件某些参数说明:
# 配置端口:
port 6379
#
tcp-backlog 511
# 只允许某些ip可以访问,可以避免攻击,默认是不打开的,这里我自己打开了
bind 127.0.0.1
#
timeout 0
#
tcp-keepalive 0
#
loglevel notice
# 配置日志打印文件地址,如果没有指定路径就会打印到控制台
logfile ""
# 数据库数量配置,redis数据库数量不像mysql可以任意添加,redis只能通过配置的方式指定,redis服务启动后就会生成指定数量的数据库,redis数据库是以数字自动命名的,默认使用第一个数据库,即索引为0的数据库
databases 16
# 备份数据到磁盘 ,save 时间间隔 变化键数量 ,表示多少秒后有几个键被修改时才会备份,时间没到是不会备份的
save 900 1
save 300 10
save 60 10000
#
stop-writes-on-bgsave-error yes
# 当某些数据被保存到磁盘中时是否进行压缩,压缩可节省控件但是不利于cpu
rdbcompression yes
#
rdbchecksum yes
# 保存到磁盘数据文件的名称,数据保存到磁盘后,每次使用数据时会从磁盘中读取,可以提升速度
dbfilename dump.rdb
# 保存到磁盘文件的路径
dir ./
#
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
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
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-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
#
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
15.我们此时可以Win+R启动命令行并在命令行启动redis服务,这里为了方便我写一个以bat结尾的启动脚本(start_redis_server.bat)双击进行启动,start_redis_server.bat启动脚本代码为:
redis-server.exe redis.windows.conf
16.此时我们双击start_redis_server.bat文件可以看到黑窗口一闪而过,之后到服务中可以看到redis服务已经运行!
17.启动redis客户端,此时可以双击redis-cli.exe,就会启动一个以127.0.0.1:6379的客户端,此时可以在此窗口进行数据增删改查等操作,通常情况下我会写一个bat结尾的程序(redis_client.bat)来指定ip和端口来连接到远程服务器上,连接到远程服务器脚本,redis_client.bat脚本如下(实际中写服务器ip和port即可):
redis-cli.exe -h 127.0.0.1 -p 6379
设置redis密码
1.通过以上安装redis可以知道基本的启动连接redis,可以发现和安装mysql不一样的是没有输入密码,这是因为redis默认是不需要密码的,当然可以自己设置密码,其命令为(注意严格大小写):
CONFIG set requirepass '你自己的密码'
2.密码验证:当设置完密码退出客户端并重新进入后,无密码验证操作redis时会提示无法操作,此时可以进行密码验证(每次进入客户端只需要验证一次就可以),密码验证命令(注意大小写):如
AUTH '你的密码'
3.密码失效时间,当关闭redis服务后,再次进入redis服务时密码就会失效。
终端操作redis数据库:
1.以key-value的方式操作数据:
//存数据:set key value ,如果key相同的话,后面的value会覆盖前面相同的key的值 如:set name '小明'
//读数据:get key 如:get name
//判断数据是否存在:exists key 如: exists name
//删除数据:del key 如:del name
2.以哈希表的形式操作数据库:
//存数据: hmset key(主键) 字段1 值1 字段2 值2 ,如: hmset user_1 name '小明' age 18
//查某个key下所有字段数据: hgetallkey key 如:hgetall user_1
//查某个key下某个字段是否存在:hexists key 字段 如:hexists user_1 name
//查某个key下某个字段的值:hget key 字段 或 hmget key 字段 如:hget user_1 name 或 hmget user_1 name
//查某个key下所有字段:hkeys key 如 :hkeys user_1
3.列表形式操作数据库:
列表类似数组,每个key表示一个数组,如下:
//往数组左边(前面)存数据:lpush key value , 如:lpush arr1 A
//往数据右边(后面)存数据:rpush key value , 如:rpush arr1 B
//从某个索引开始列出到某个索引结束的数据:larnge key start stop 如:larnge arr1 0 2
//从左边/右边删除某个列表值:lpop/rpop key 如:lpop arr1
4.有序集合:
有序集合一般可用于权重排序,具体使用如下:
//添加要排序的元素:zadd key 权重 值,如:zadd grade 10 a
//根据权重排序显示前几位值:zrange key start stop 如:zrange grade 0 10
//根据权重排序显示权重分值和值:zrange key start stop withscopes
注意:权重小的会先显示出来,权重大的最后显示,需要注意,包括以上列表,最后添加的元素会显示在最前面(以lpush为准)。
nodejs操作redis:
redis是一个支持多语言的数据库,这里我以nodejs操作redis为例,简单介绍redis在编程中的使用步骤。
nodejs操作redis可以使用第三方基于node实现redis通信的客户端模块,其具体使用步骤如下:
1.下载安装redis包:注意,在测试过程中redis版本过高会报错,我这里使用的是redis@3.1.2
npm install redis@3.1.2
2.在需要使用的文件引入redis:
const redis = require('redis')
3.创建一个redis客户端:
const redisClient = redis.createClient(option)
4.调用redis客户端的api,以set为例:
redisClient.set(key,value,callback)
node实际开发中使用如下:
封装redis客户端:
// 导入redis缓存包:
const redis = require('redis')
// 配置信息:
const option = {
host: '127.0.0.1',
port: 6379,
db: 0, // redis数据库以数字表示,这里是和mysql之间的区别
// password: '123456a',
detect_buffers: true, // 传入buffer 返回也是buffer 否则会转换成String
retry_strategy: function (opt) {
// 重连机制
if (opt.error && opt.error.code === "ECONNREFUSED") {
return new Error("The server refused the connection")
}
if (opt.total_retry_time > 1000 * 60 * 60) {
return new Error("Retry time exhausted")
}
if (opt.attempt > 10) {
// End reconnecting with built in error
return undefined
}
// reconnect after
return Math.min(opt.attempt * 100, 3000)
}
}
// 创建redis客户端
const redisClient = redis.createClient(option)
// 准备连接redis-server事件
redisClient.on('ready', function () {
// console.log('Redis redisClient: ready')
})
// 连接到redis-server回调事件
redisClient.on('connect', function () {
// console.log('redis is now connected!')
})
redisClient.on('reconnecting', function () {
// console.log('redis reconnecting')
})
redisClient.on('end', function () {
// console.log('Redis Closed!')
})
redisClient.on('warning', function (err) {
console.log('Redis redisClient: warning,'+ err)
})
redisClient.on('error', function (err) {
console.error('Redis Error ' + err)
})
// 导出redis客户端:
module.exports = redisClient
调用node_redis中的api,这里和命令行中命令相同,以短信注册用户接口为例如下(注意:接口中的部分模块没有引入,但是不受学习,实际测试中嵌入自己接口实现效果即可):
封装发短信模块:
// 引入redis客户端:
const redisClient = require('./redisconf')
// 发短信功能模块的封装:
//调用阿里短信平台的框架
const SMSClient = require('@alicloud/sms-sdk')
//短信云平台获取accessKeyId(下面是假值)
const accessKeyId = 'AeAm*******j5LTrKLJV'
//短信云平台获取accessKeySecret(下面是假值)
const secretAccessKey = 'TfRSFe*********56eWvPwwZ44J8C'
//创建一个发送短信的实例
let smsClient = new SMSClient({accessKeyId,secretAccessKey})
//发送短信功能封装为函数供其它需要发送短信的地方调用
let sendSmsCode = async (phone,verCode) => {
try {
// 校验参数是否为空:
if (!phone) throw ('缺少号码')
if (!verCode) throw ('缺少验证码')
// 配置请求参数:
let dataToSend = {
//传入手机号码
PhoneNumbers: phone,
//短信云平台获取签名
SignName:'苦海',
//短信云平台获取模板编码(下面是假值)
TemplateCode:'SMS_36*****888',
//将对象转换为json字符串后赋值给后面TemplateParam
TemplateParam: JSON.stringify({ code: verCode })
}
//调用smsClient实例的方法:sendSMS,通知阿里云发送验证码
let smsResponse = await smsClient.sendSMS(dataToSend)
// 结构出Code状态码判断是否发送成功
let { Code } = smsResponse
// 发送成功后将验证码以手机号码为key,验证码为value的方式,临时存到redis中并将结果返回给方法sendLoginCroeCode调用者,这里不返回也没问题,可以不用返回,因为发短信和注册接口是两个独立的接口,只是验证码需要临时存到redis中
if (Code === 'OK') {
// 将验证码和号码存到redis缓存中,以号码为key,验证码为value形式:
redisClient.set(phone,verCode,(err) => {
if (err) {
console.log('验证码存到redis错误:' + err)
}
})
// 设置60秒过期时间,无论是否校验通过,60秒后都清楚数据
redisClient.expire(phone,60)
// 将结果返回调用者
return smsResponse
}
// 当发送失败时抛出异常:
throw '短信发送失败!'
} catch (error) {
console.log('发送短信验证码失败,您的操作可能过于频繁,请稍微再试!'+error)
}
}
// 导出此方法:
module.exports = sendSmsCode
发短信接口:
// 引入redis客户端:
const redisClient = require('../config/redisconf')
// 获取短信验证码接口
router.post('/api/regist',(request,response)=>{
let {phone} = request.body
let smsCode = String(1000 + parseInt(Math.random() * 1000000)).slice(0, 4)
// 调用发短信方法进行发送验证码:
let verCode = sendSmsCode(phone,smsCode)
if (verCode) {
response.send({cod: 200, msg: '获取短信验证码成功!'})
} else {
response.send({cod: 201, msg: '获取短信验证码失败!'})
}
})
验证码校验并注册:
// 注册用户接口:
router.post('/api/register',(request,response) => {
const {userName, passWord, phone, authCode} = request.body
let sql1 = 'SELECT * FROM `theuser` WHERE user_name = "'+userName+'"'
// 判断此用户是否存在
function isExistUserName () {
return new Promise((resolve) => {
connection.query(sql1,(error, results) => {
try {
if (error) {
throw error
} else {
resolve(results)
}
} catch (err) {
console.log('regestserve文件注册用户接口中判断此用户是否存在错误:' + err)
}
})
})
}
// 新增用户:
async function addNewTheuser () {
// 查询用户名是否存在
let isExist = await isExistUserName()
// 用户名不存在时
if (isExist.length === 0) {
// 自己封装的获取当前时间并格式化的函数:
let timer = dateFormatter1()
let sql2 = "INSERT INTO `projectdataroot`.`theuser` (`user_name`, `user_password`, `user_phone`, `user_create_date`) VALUES ('"+userName+"', '"+passWord+"', '"+phone+"', '"+timer+"')"
// 从redis中获取验证码并做校验:
redisClient.get(phone,(error,smsCode)=>{
if (error) {
throw error
} else {
// 判断验证码是否正确
if (authCode === smsCode) {
connection.query(sql2,(error)=>{
try {
if (error) {
throw error
} else {
response.send({cod: 200, msg: '注册成功!'})
// 注册成功后立即删除redis中的校验码
redisClient.del(phone,(error=>{
if (error) {
console.log('删除redis短信验证码数据失败:'+ error)
}
}))
}
} catch (err){
console.log('regestserve文件注册用户接口中新增用户存在错误:' + err)
}
})
} else {
response.send({cod: 202, msg: '短信验证码不正确!'})
}
}
})
} else {
response.send({cod: 201, msg: '用户已存在!'})
}
}
addNewTheuser()
})
提示:本文图片等素材来源于网络,若有侵权,请发邮件至邮箱:810665436@qq.com联系笔者 删除。
笔者:苦海