一、引言
在Web应用发展的初期,那时关系型数据库受到了较为广泛的关注和应用,原因是因为那时候Web站点基本上访问和并发不高、交互也较少。而在后来,随着访问量的提升,使用关系型数据库的Web站点多多少少都开始在性能上出现了一些瓶颈,而瓶颈的源头一般是在磁盘的I/O上。而随着互联网技术的进一步发展,各种类型的应用层出不穷,这导致在当今云计算、大数据盛行的时代,对性能有了更多的需求,主要体现在以下几个方面:
- 低延迟的读写速度:应用快速地反应能极大地提升用户的满意度
- 支撑海量的数据和流量:对于搜索这样大型应用而言,需要利用PB级别的数据和能应对百万级的流量
- 大规模集群的管理:系统管理员希望分布式应用能更简单的部署和管理
为了克服这一问题,NoSQL应运而生,它同时具备了高性能、可扩展性强、高可用等优点,受到广泛开发人员和仓库管理人员的青睐。
关系型数据库(RMDBS)与非关系型数据库(NoSQL)的对比:
数据库中表与表的数据之间存在某种关联的内在关系,因为这种关系,所以我们称这种数据库为关系型数据库。典型:Mysql/MariaDB、postgreSQL、Oracle、SQLServer、DB2、Access、SQLlite3。特点:
- 全部使用SQL(结构化查询语言)进行数据库操作。
- 都存在主外键关系,表,等等关系特征。
- 大部分都支持各种关系型的数据库的特性:事务、存储过程、触发器、视图、临时表、模式、函数
NOSQL:not only sql,泛指非关系型数据库。泛指那些不使用SQL语句进行数据操作的数据库,所有数据库中只要不使用SQL语句的都是非关系型数据库。典型:Redis、MongoDB、hbase、 Hadoop、elasticsearch、图数据库(Neo4j、GraphDB、SequoiaDB)
二、redis介绍
Redis(Remote Dictionary Server ,远程字典服务) 是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性(可以平移到磁盘上)的键值对存储数据库,是NoSQL数据库。
redis的出现主要是为了替代早期的Memcache缓存系统的。map内存型(数据存放在内存中)的非关系型(nosql)key-value(键值存储)数据库,Memcache的Value只能是字符串。
支持数据的持久化(基于RDB和AOF),注: 数据持久化时将数据存放到文件中,每次启动redis之后会先将文件中数据加载到内存,经常用来做缓存、数据共享、购物车、消息队列、计数器、限流等。(最基本的就是缓存一些经常用到的数据,提高读写速度)。
redis特性:
- 速度快
- 持久化
- 多种数据结构
- 支持多种编程语言
- 主从复制
- 高可用、分布式
2.2、Redis的数据类型及主要特性
Redis提供的数据类型主要分为5种自有类型和一种自定义类型,这5种自有类型包括:String类型、哈希类型、列表类型、集合类型和顺序集合类型。值不支持数字类型
例如:
redis={
"name":"yuan",
"age":"23", # 不能是数字23,即使你设置的时候是23但是存的时候还是“23”
"scors":[78,79,98,],
"info":{"gender":"male","tel":"110"},
"set":{1,2,3}, # 无序集合
"zset":{1,2,3,} # 有序集合
}
这里的数据类型说的是value,key是固定的(属性或者字符串)
2.3、Redis的应用场景有哪些
缓存系统(“热点”数据:高频读、低频写):缓存用户信息,优惠券过期时间,验证码过期时间、session、token等
计数器:帖子的浏览数,视频播放次数,评论次数、点赞次数等
消息队列,秒杀系统
社交网络:粉丝、共同好友(可能认识的人),兴趣爱好(推荐商品)
排行榜(有序集合)
发布订阅:粉丝关注、消息通知
三、redis环境安装(基于Windows)
- redis的官方只提供了linux版本的redis,window系统的redis是微软团队根据官方的linux版本高仿的。
- 官方原版: https://redis.io/
- 中文官网:http://www.redis.cn
3.1、下载和安装(5版本)
下载地址:https://github.com/tporadowski/redis/releases
1、使用以下命令启动redis服务端
redis-server C:/tool/redis/redis.windows.conf
关闭上面这个cmd窗口就关闭redis服务器服务了。
2、redis作为windows服务启动方式
redis-server --service-install redis.windows.conf
- 启动服务:redis-server --service-start
- 停止服务:redis-server --service-stop
# 如果连接操作redis,可以在终端下,使用以下命令:
redis-cli
3、ubuntu下安装
安装命令:sudo apt-get install -y redis-server
卸载命令:sudo apt-get purge --auto-remove redis-server
关闭命令:sudo service redis-server stop
开启命令:sudo service redis-server start
重启命令:sudo service redis-server restart
配置文件:/etc/redis/redis.conf
3.2、redis的配置
cat /etc/redis/redis.conf
redis 安装成功以后,window下的配置文件保存在软件 安装目录下,如果是mac或者linux,则默认安装/etc/redis/redis.conf
redis的核心配置选项
绑定ip:访问白名单,如果需要远程访问,可将此注释,或绑定1个真实ip
bind 127.0.0.1 xx.xx.xx.xx
端⼝,默认为6379
port 6379
是否以守护进程运行
- 如果以守护进程运行,则不会在命令阻塞,类似于服务
- 如果以守护进程运行,则当前终端被阻塞
- 设置为yes表示守护进程,设置为no表示⾮守护进程
- 推荐设置为yes
daemonize yes
RDB持久化的备份策略(RDB备份是默认开启的)
# save 时间 读写次数
save 900 1 # 当redis在900内至少有1次读写操作,则触发一次数据库的备份操作
save 300 10 # 当redis在300内至少有10次读写操作,则触发一次数据库的备份操作
save 60 10000 # 当redis在60内至少有10000次读写操作,则触发一次数据库的备份操作
RDB持久化的备份文件
dbfilename dump.rdb
RDB持久化数据库数据文件的所在目录
dir /var/lib/redis
日志文件所载目录
loglevel notice
logfile /var/log/redis/redis-server.log
进程ID文件
pidfile /var/run/redis/redis-server.pid
数据库,默认有16个,数据名是不能自定义的,只能是0-15之间,当然这个15是数据库数量-1
database 16
redis的登录密码,生产阶段打开,开发阶段避免麻烦,一般都是注释的。redis在6.0版本以后新增了ACL访问控制机制,新增了用户管理,这个版本以后才有账号和密码,再次之前只有没有密码没有账号
# requirepass foobared
注意:开启了以后,redis-cli终端下使用 auth 密码
来认证登录。
AOF持久化的开启配置项(默认值是no,关闭状态)
appendonly no
AOF持久化的备份文件(AOF的备份数据文件与RDB的备份数据文件保存在同一个目录下,由dir配置项指定)
appendfilename "appendonly.aof"
AOF持久化备份策略[时间]
# appendfsync always
appendfsync everysec # 工作中最常用。每一秒备份一次
# appendfsync no
哨兵集群:一主二从三哨兵(3台服务器)
3.3 Redis的使用
redis是一款基于CS架构的数据库,所以redis有客户端redis-cli,也有服务端redis-server。
其中,客户端可以使用go、java、python等编程语言,也可以终端下使用命令行工具管理redis数据库,甚至可以安装一些别人开发的界面工具,例如:RDM。
redis-cli客户端连接服务器:
# redis-cli -h `redis服务器ip` -p `redis服务器port`
redis-cli -h 10.16.244.3 -p 6379
四、redis数据类型
redis可以理解成一个全局的大字典,key就是数据的唯一标识符。根据key对应的值不同,可以划分成5个基本数据类型。
redis = {
"name":"yuan",
"scors":["100","89","78"],
"info":{
"name":"rain"
"age":22
},
"s":{item1,itme2,..}
}
1. string类型:
字符串类型,是 Redis 中最为基础的数据存储类型,它在 Redis 中是二进制安全的,也就是byte类型。
`单个数据的最大容量是512M`。
key: 值
2. hash类型:
哈希类型,用于存储对象/字典,对象/字典的结构为键值对。key、域、值的类型都为string。域在同一个hash中是唯一的。
key:{
域(属性): 值,
域:值,
域:值,
域:值,
...
}
3. list类型:
列表类型,它的子成员类型为string。
key: [值1,值2, 值3.....]
4. set类型:
无序集合,它的子成员类型为string类型,元素唯一不重复,没有修改操作。
key: {值1, 值4, 值3, ...., 值5}
5. zset类型(sortedSet):
有序集合,它的子成员值的类型为string类型,元素唯一不重复,没有修改操作。权重值(score,分数)从小到大排列。
key: {
值1 权重值1(数字);
值2 权重值2;
值3 权重值3;
值4 权重值4;
}
4.1. string(字符串)
- SET/SETEX/MSET/MSETNX
- GET/MGET
- GETSET
- INCR/DECR
- DEL
4.1.1 设置键值
set 设置的数据没有额外操作时,是不会过期的。
set key value
设置键为name
值为yuan
的数据
set name yuan
set name rain # 一个变量可以设置多次
注意:redis中的所有数据操作,如果设置的键不存在则为添加,如果设置的键已经存在则修改。
设置一个键,当键不存在时才能设置成功,用于一个变量只能被设置一次的情况。
setnx key value
一般用于给数据加锁(分布式锁)
127.0.0.1:6379> setnx goods_1 101
(integer) 1
127.0.0.1:6379> setnx goods_1 102
(integer) 0 # 表示设置不成功
127.0.0.1:6379> del goods_1
(integer) 1
127.0.0.1:6379> setnx goods_1 102
(integer) 1
4.1.2 设置键值的过期时间
redis中可以对一切的数据进行设置有效期。以秒为单位
setex key seconds value
设置键为goods_1
值为101
过期时间为10秒的数据
setex name goods_1 10
4.1.3 关于设置保存数据的有效期
setex 添加保存数据到redis,同时设置有效期,格式:
setex key time value
4.1.4 设置多个键值
mset key1 value1 key2 value2 ...
例3:设置键为a1
值为goland
、键为a2
值为java
、键为a3
值为`c
mset a1 goland a2 java a3 c
4.1.5 字符串拼接值
常见于大文件上传
append key value
向键为a1
中拼接值`haha
set title "我的"
append title "redis"
append title "学习之路"
4.1.6 根据键获取值
根据键获取值,如果不存在此键则返回nil
get key
获取键name
的值
get name
根据多个键获取多个值
mget key1 key2 ...
获取键a1、a2、a3
的值
mget a1 a2 a3
getset:设置key的新值,返回旧值
redis> GETSET db mongodb # 没有旧值,返回 nil
(nil)
redis> GET db
"mongodb"
redis> GETSET db redis # 返回旧值 mongodb
"mongodb"
redis> GET db
"redis"
4.1.7 自增自减
web开发中的电商抢购、秒杀。游戏里面的投票、攻击计数。系统中计算当前在线人数
set id 1
incr id # 相当于id+1
get id # 2
incr id # 相当于id+1
get id # 3
set goods_id_1 10
decr goods_id_1 # 相当于 id-1
get goods_id_1 # "9"
decr goods_id_1 # 相当于id-1
get goods_id_1 # 8
set age 22
incrby age 2 # 自增自减大于1的值时候用incrby
4.1.8 获取字符串的长度
set name xiaoming
strlen name # 8
4.1.9 比特流操作
1字节=8比特 1kb = 1024字节 1mb = 1024kb 1gb = 1024mb
1个int8
就是一个字节,一个中文:3
个字节
SETBIT # SETBIT key offset value 按从左到右的偏移量设置一个bit数据的值
GETBIT # 获取一个bit数据的值
BITCOUNT # 统计字符串被设置为1的bit数.
BITPOS # 返回字符串里面第一个被设置为1或者0的bit位。
我们知道 ‘a’ 的ASCII码是 97。转换为二进制是:01100001。offset的学名叫做“偏移” 。二进制中的每一位就是offset值啦,比如在这里 offset 0 等于 ‘0’ ,offset 1等于 ‘1’ ,offset 2 等于 ‘1’,offset 6 等于 ‘0’ ,没错,offset是从左往右计数
的,也就是从高位往低位。
我们通过SETBIT 命令将 andy中的 ‘a’ 变成 ‘b’ 应该怎么变呢?
也就是将 01100001 变成 01100010 (b的ASCII码是98),这个很简单啦,也就是将’a’中的offset 6从0变成1,将offset 7 从1变成0 。
案例1:
SETBIT mykey 7 1
# 00000001
getbit mykey 7
# 00000001
SETBIT mykey 4 1
# 00001001
SETBIT mykey 15 1
# 0000100100000001
案例2:签到系统
setbit user_1 6 1
setbit user_1 5 1
setbit user_1 4 0
setbit user_1 3 1
setbit user_1 2 0
setbit user_1 1 1
setbit user_1 0 1
BITCOUNT user_1 # 统计一周的打卡情况