redis基础
redis基础
本文思路
本文将以大数据时代的数据特点和需求为起步,引出Nosql数据库和分布式数据库,并简要介绍Nosql的数据模型、分类,以及分布式数据的CAP等原理,最后着重介绍属于Nosql数据库和分布式数据库的redis。
大数据时代的数据特点和需求
目前大数据时代的数据具有3V的特性:海量(Volume),多样(Variety),实时(Velocity),而目前互联网的需求在于高并发,高可扩,高性能。原本的关系型数据库难以存储海量和多样的数据,集中式的数据库难以满足高并发和高可扩的需求,
Nosql数据库
数据模型
聚合模型分别有:KV键值,bson,列族,图形。
bson样例,和json样式上类似:
{
name:"lemo",
age:"12",
address:{
city:"suzhou",
country:"china",
code:215000
} ,
scores:[
{"name":"english","grade:3.0},
{"name":"chinese","grade:2.0}
]
}
列族:
图形:
数据库分类
不同的数据模型,分成了不同的数据库种类。
以下是该分类典型的数据库
kv键值:redis
文档型数据库(Bson格式比较多):CouchDB,MongoDB
列存储数据库:Cassandra, HBase ,分布式文件系统
图关系数据库:Neo4J, InfoGrid
分布式数据库的设计遵循原理
传统的ACID
- A (Atomicity) 原子性
- C (Consistency) 一致性
- I (Isolation) 独立性
- D (Durability) 持久性
关系型数据库一般是都严格遵循的。
CAP
- C:Consistency(强一致性)
- A:Availability(可用性)
- P:Partition tolerance(分区容错性)
CAP理论是说在分布式存储系统中,最多只能实现上面的两点,所有会有三种类型:
CA 传统Oracle数据库;
AP 大多数网站架构的选择 ;
CP Redis、Mongodb;
而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。注意:分布式架构的时候必须做出取舍。一致性和可用性之间取一个平衡。多余大多数web应用,其实并不需要强一致性。因此牺牲C换取P,这是目前分布式数据库产品的方向
BASE
BASE就是为了解决关系数据库强一致性引起的问题而引起的可用性降低而提出的解决方案。BASE其实是下面三个术语的缩写: 基本可用(Basically Available) 软状态(Soft state) 最终一致(Eventually consistent)
它的思想是通过让系统放松对某一时刻数据一致性的要求来换取系统整体伸缩性和性能上改观。为什么这么说呢,缘由就在于大型系统往往由于地域分布和极高性能的要求,不可能采用分布式事务来完成这些指标,要想获得这些指标,我们必须采用另外一种方式来完成,这里BASE就是解决这个问题的办法
Redis
简介
Redis:REmote DIctionary Server(远程字典服务器)。
Redis是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器
特点:
- Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
- Redis支持数据的备份,即master-slave模式的数据备份
用途
- 内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
- 取最新N个数据的操作,如:可以将最新的10条评论的ID放在Redis的List集合里面
- 给定数据有效时限:模拟类似于HttpSession这种需要设定过期时间的功能
- 发布、订阅消息系统(一般不使用redis做消息系统)
- 定时器、计数器
bin文件中各文件的作用
- redis-benchmark:性能测试工具,可以在自己本子运行,看看自己本子性能如何(需要启动服务后)
- redis-check-aof:修复有问题的AOF文件
- redis-check-dump:修复有问题的dump.rdb文件
- redis-cli:客户端,操作入口
- redis-sentinel:redis集群使用
- redis-server:Redis服务器启动命令
服务开启和关闭方法
开启:
- 修改redis.conf:将里面的daemonize no 改成 yes,让服务在后台启动
- 将redis.conf拷贝至另外的文件夹(原配置文件不进行其他参数的修改)
- 然后在拷出的文件夹中,运行 redis-cli -p 6379
关闭:
- 单实例关闭:redis-cli shutdown
- 多实例关闭,指定端口关闭:redis-cli -p 6379 shutdown
基础
- Redis 默认有16个数据库,从零开始,默认使用零号库,数量可以通过配置修改
- select命令切换数据库
- dbsize查看当前数据库的key的数量
- flushdb:清空当前库
- Flushall;清空全部库
- 统一密码管理,16个库都是同样密码
- Redis索引都是从零开始
redis支持的数据类型
- string 字符串
- hash 哈希,类似于map
- list 列表
- set 集合
- zset 有序集合
key 相关操作指令
查询匹配的key
#格式:keys [正则]
#例如:查询所有key
keys *
判断key是否存在
# 描述:判断key是否存在
# 格式:exists [key的名称]
exists k1
将key迁移到其他库
# 格式: move [key的名称] [要迁移到的库]
# 描述:将key:k1 从当前库迁移到1库,当前库key:k1不再存在
move k1 1
例子:
为给定的key设置过期时间
# 格式: expire [key的名称] [秒钟]
# 描述:过期key被删除
# yw有效期2秒
expire yw 2
例子
查看key过期时间(单位:秒)
# 格式:ttl [key的名称]
# 描述:查看还有多少秒过期,-1表示永不过期,-2表示已过期
例子:
查看key类型
# 格式: type [key的名称]
例子:
String相关操作指令
特点:单值单value
添加值
(1)set 单个添加
# 格式:set [key名称] [值]
# 其中的值,可以说String 或 数字
(2) setex 添加key的同时设置有效时间
# 格式:setex [key名称] [有效时间] [值]
例子:
(3) setnx 如果key不存在,则添加key,如果已存在则不添加
# 格式:setnx [key名称] [值]
# 如果添加不成功,返回0
例子:
(4) mset 批量添加
# 格式:mset [key名称] [值] [key名称] [值][key名称] [值] ...
(5)msetnx 批量添加如果key不存在,则添加key,如果已存在则不添加
# 格式:msetnx [key名称] [值] [key名称] [值][key名称] [值] ...
删除值
(1) del 删除key
# 格式:del [key名称]
修改值
(1)value 为 字符串型
a.在字符串后面追加值
# 格式: append [key名称] [追加的值]
例子:
b.范围内替换值
# 格式:setrange [key名称] [替换起始下标] [替换值]
# 描述:替换起始下标从0开始计算,按照替换值的长度等量替换
(2) value为数字类型
a. 加1
# 格式: incr [key名称]
b.减1
# 格式:decr [key名称]
c. 加 任意值
# 格式:incrby [key名称] [任意值]
d. 减任意值
# 格式:decrby [key名称] [任意值]
查询值
(1)获取单个key的值
# 格式:get [key名称]
(2) 获取多个key的值
# 格式:mget [key名称] [key名称] ...
(3)获取key的值字符串长度
# 格式:strlen [key名称]
(4)获取key的值 字符串中部分
# 格式:getrange [key名称] [起始下标] [结束下标]
# 描述:获取起始下标到结束下标的值
先获取key的值,在对key进行赋值
# 格式:getset [key名称] [赋值的值]
List相关操作指令
创建或往list中追加值
(1)lpush 将一个或多个值 value
插入到列表 key
的表头 ,若该key不存在,则创建key,并添加值
# 格式: lpush [key名称] [值1] [值2] ...
(2) rpush 将一个或多个值 value
插入到列表 key
的表尾(最右边) , 如果 key
不存在,一个空列表会被创建并执行 RPUSH 操作。
# 格式: rpush [key名称] [值1] [值2] ...
(3)linsert 在list某个已有值的前后再添加具体值
# 格式: linsert [key] before/after [value1] [value2]
查询list中值
(1) lrange 返回列表 key
中指定区间内的元素,区间以偏移量 start
和 stop
指定。
# 格式: lrange [key名称] [start] [stop]
# 注意: stop对应的下标元素是包含在内的
(2)lindex 返回列表 key
中,下标为 index
的元素。
# 格式: lindex [key名称] [index]
(3) llen 返回列表 key
的长度
# 格式: llen [key名称]
移除值
(1)lpop 移除并返回列表 key
的头元素
# 格式:lpop [key名称]
(2)rpop 移除并返回列表 key
的尾元素
# 格式:rpop [key名称]
(3) lrem 根据参数 count
的值,移除列表中与参数 value
相等的元素
# 格式:lrem [key] [count] [value]
# 注意:count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
# count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
# count = 0 : 移除表中所有与 value 相等的值。
(4) ltrim 移除区间外的值
# 格式: ltrim [key] [start] [stop]
# 描述: 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。举个例子,执行命令 LTRIM list 0 2 ,表示只保留列表 list 的前三个元素,其余元素全部删除。
先移除再添加
(1) rpoplpush 将一个列表中的尾元素弹出(移除),添加到另一个列表中表头
# 格式:rpoplpush [source] [destination]
修改列表中的值
(1)lset 修改列表中某个下标的值
# 格式: lset [key] [index] [value]
# 描述: 将列表 key 下标为 index 的元素的值设置为 value 。
Set相关操作指令
添加值
(1)sadd 将一个或多个 member
元素加入到集合 key
当中,已经存在于集合的 member
元素将被忽略。
# 格式: sadd [key] [member] [member] ...
查询值
(1)smembers 查询集合中所有的值
# 格式: smembers [key]
(2)sismember 判断值是否是集合中的成员
# 格式:sismember [key] [value]
(3)scard 查询集合中有多少个元素
# 格式: scard [key]
(4)srandmember 随机查询集合中指定数量的值
# srandmember [key] [count查询数量]
删除值
(1)srem 删除集合中某元素
# 格式: srem key value
(2)spop 随机删除指定数量的元素
# 格式:spop [key] [count]
移动值(将值从一个集合移动到另一个集合)
(3)smove 将值从一个集合移动到另一个集合
smove [oldkey] [newkey] [member]
数学集合操作
(1)差集:在第一个set里面而不在后面任何一个set里面的成员
sdiff [key1] [key] ...
(2)交集:所有set中共有的成员
sinter [key] [key] ...
(3)并集:所有set中所有元素的集合
sunion [key] [key] ...
哈希表相关操作
添加值
(1)hset 添加hash键值对
hset [key] [field] [value] [field] [value] ...
描述:将哈希表 hash
中域 field
的值设置为 value
。
如果给定的哈希表并不存在, 那么一个新的哈希表将被创建并执行 HSET
操作。
如果域 field
已经存在于哈希表中, 那么它的旧值将被新值 value
覆盖。
(2)hmset 添加hash多个键值对
hmset [key] [field] [value] [field] [value] ...
hset也能添加多个
(3) hsetnx 当且仅当域 field
尚未存在于哈希表的情况下, 将它的值设置为 value
。
hsetnx [key] [field] value
如果给定域已经存在于哈希表当中, 那么命令将放弃执行设置操作。
如果哈希表 hash
不存在, 那么一个新的哈希表将被创建并执行 HSETNX
命令。
查询值
(1)hget 查询哈希表中某个键的值
hget [key] [field]
返回哈希表中给定域的值。
(2)hmget 查询哈希表中多个键的值
hmget [key] [field] [field] [field]
返回哈希表 key
中,一个或多个给定域的值。
如果给定的域不存在于哈希表,那么返回一个 nil
值。
因为不存在的 key
被当作一个空哈希表来处理,所以对一个不存在的 key
进行 HMGET操作将返回一个只带有 nil
值的表。
(3) hgetall 返回哈希表中所有的域和值
返回哈希表 key 中,所有的域和值。
在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。
(4) hlen 查询哈希表中域数量
hlen [key]
(5) hexists 判断field是否在哈希表中
hexists [key] [field]
(6) hkeys 查询哈希表中的所有的域
hkeys [key]
(7) hvals 查询哈希表中所有域的值
hvals [key]
删除
(1)hdel 删除哈希表 key
中的一个或多个指定域,不存在的域将被忽略
hdel [key] [field] [field] ...
修改
(1)hincrby 为哈希表 key
中的域 field
的值加上增量 increment
。
hincrby [key] [field] [increment]
增量也可以为负数,相当于对给定域进行减法操作。
如果 key
不存在,一个新的哈希表被创建并执行 HINCRBY命令。
如果域 field
不存在,那么在执行命令前,域的值被初始化为 0
。
对一个储存字符串值的域 field
执行 HINCRBY 命令将造成一个错误。
本操作的值被限制在 64 位(bit)有符号数字表示之内。
(2) hincrbyfloat 为哈希表 key
中的域 field
加上浮点数增量 increment
。
hincrbyfloat [key] [field] [increment]
如果哈希表中没有域 field
,那么 HINCRBYFLOAT会先将域 field
的值设为 0
,然后再执行加法操作。
如果键 key
不存在,那么 HINCRBYFLOAT 会先创建一个哈希表,再创建域 field
,最后再执行加法操作。
当以下任意一个条件发生时,返回一个错误:
- 域
field
的值不是字符串类型(因为 redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型) - 域
field
当前的值或给定的增量increment
不能解释(parse)为双精度浮点数(double precision floating point number)
转载自:https://juejin.cn/post/7280787122004983823