赞
踩
中间件是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的。它并没有很严格的定义,但是普遍接受IDC的定义:中间件是一种独立的系统软件服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源,中间件位于客户机服务器的操作系统之上,管理计算资源和网络通信。从这个意义上可以用一个等式来表示中间件:中间件=平台+通信,这也就限定了只有用于分布式系统中才能叫中间件,同时也把它与支撑软件和实用软件区分开来。——《百度词条》
分库分表(水平切分、垂直切分、读写分离)也可以减少IO压力,但是会破坏业务逻辑。
NoSQL(not only sql),泛指非关系型数据库。
不依赖业务逻辑方式存储,而是以简单的键值对(key-value)模式存储。
不是以逻辑为优先级,而是以性能为优先。
(宝塔等服务器管理程序可以一键安装部署)
官网下载
注意,Redis Stack是另外一个产品,是由多个模块组成的。此外,Redis官方的产品,是不支持Windows系统的。
笔者使用的是Redis 7.0。
测试gcc环境,确认是否安装C环境(一般都自带)
gcc --version
如果没有的化,需要安装C语言编译环境。
笔者使用的是yum命令,如果是其他Linux社区的虚拟机请自行查阅相关命令。
#yum install centos-release-scl scl-utils-build
#yum install -y devtoolset-8-toolchain
#scl enable devtoolset-8 bash
tar -zxvf redis-7.0.2.tar.gz
完成后进入解压后的文件,(如下图)在redis-7.0.2目录下,
使用编译命令make,完成编译操作,以保证兼容当前平台。
若出现Jemalloc/jemalloc.h致命错误,确定是否gcc安装成功。若已成功,可以尝试用make distclean,清楚所有的编译文件,再试一次。(笔者直接成功的,因此不清楚是否是gcc版本问题或是其他原因)
成功编译了以后,调用install完成文件安装。
make installl
可以在该文件下进行测试,以保证正确编译、安装。
make test
默认执行程序安装在/usr/local/bin 文件下
就是通过命令行启动它
redis-server
即通过配置文件启动。
我们将我们解压文件中的redis.conf 复制导 /etc 下,通过修改文件中的 daemonize no 为daemonize yes,即可。
通过启动下述命令即可。
redis-server /etc/redis.conf
可以看到已经启动了
通过redis-cli从客户端连接
开源的键值对存储系统。默认端口为6379。
基本类型:
有 push/pop、add/remove与取 交集并集 等操作。操作也都是原子性的。
Redis会周期性的把更新的数据写入磁盘或把修改操作写入追加的记录文件之中。也实现了主从同步。
通常配合关系型数据库做高速缓存。
默认有16个数据库,0~15,初始默认使用0号数据库。切换数据库:
select <dbid,数据库编号>
指的是使用一个线程来检查多个文件描述符(socket)的就绪状态。比如使用select,poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。得到就绪态后,及逆行真正的操作可以在同一个线程里面执行,也可以启动线程执行。
请求方发出请求后,就可以做其他事情了。处理的部分有结果后,会返回结果给请求方。
连接上后,我们进行操作。
操作是原子的,因为它是单线程+多路IO。
查看所有key
keys *
添加key或修改值,有效时间无限
set <key> <value>
获取value
get <key>
key是否存在
exists <key>
键的类型
type <key>
删除键
del <key>
非阻塞删除,仅将key从keyspace元数据中删除,真正的删除会在后续异步操作
unlink <key>
设置或更新key的有效时间
expire <key> <time,单位为秒>
查看key有效时间,-2表示已经过期,-1表示永不过期,正整数表示还有多久过期
ttl <key>
此外,redis的范围操作大多数都是闭区间,而非我们常用的左闭右开区间。
切换库(默认0~15)
select <index>
查看当前数据库的key的数量
dbsize
清空当前库,后面可以选择异步或同步操作
flushdb
清除全部库,后面可以选择异步或同步操作
flushall
二进制安全(binary safe)是一种主要用于字符串操作函数相关的计算机编程术语。一个二进制安全函数,其本质上将把输入内容作为原始的、无任何特殊格式意义的数据流进行处理。
比如C/C++字符数组以’\0’结束,ASCLL码与二进制不能完全对等转等等。如果我们将二进制存储为字符串,或将字符串转换为二进制,就会出问题。
添加key或修改值,有效时间无限
set <key> <value>
获取value
get <key>
设置key并设置有效时间
setex <key> <time,单位为秒><value>
增加字符串,返回加入后的总长度
append <key> <value>
获取值的长度
strlen <key>
取得旧值,同时设置新值
getset <key> <value>
设置key的值,,有效时间无限。但它不能覆盖或替换已有值。即,key必须不存在。
setnx <key> <value>
获取范围值,类似java中的String.substring(),C++中的string.substr(),-1代表末尾,是闭区间
getrange <key><start><end>
设置范围值,从0开始
setrange <key><start> <value>
批量设置
mset <key1> <value1> <key2> <value2>…
批量设置不存在的key(原子性,一个失败全部失败)
msetnx <key1> <value1> <key2> <value2>…
批量获取
mget <key1> <value1> <key2> <value2>…
值自增1,只能对数字值操作,返回结果
incr <key>
值自减1,只能对数字值操作,返回结果
decr <key>
自定义自增步长,只能对数字值操作,负数就是自减,返回结果
incrby <key> <步长>
自定义自增步长,只能对数字值操作,负数就是自增,返回结果
decrby <key> <步长>
结构为简单动态字符串(Simple Dynamic String,SDS)。是一个可以修改的字符串,实现上类似Java的ArrayList或者C++的Vector,使用冗余分配,减少内存频繁分配。
单键多值。即一个键对应一个列表。可以从列表的首尾(左右)添加元素或者删除元素。
底层实际是一个双向链表,对双端的操作性能很高,通过索引下表操作中间节点性能较差。
从左边/右边(首尾)插入一个或多个值
lpush/rpush <key> <value1> <value2>…
从左边/右边(首尾)弹出一个值。如果值全部弹出,键也被销毁。
lpop/rpop <key>
依照索引下标获取元素(首尾),-1代表末尾
lrange <key> <start> <end>
key1右侧弹出一个值,插入key2左侧
rpoplpush <key1> <key2>
索引下标获取值
lindex <key> <index>
获取列表长度
llen <key>
插入值,在value之后/前(靠近左侧/首部为前,取第一个值相同的)插入newvalue
linsert <key> before/after <value> <newvalue>
从左侧(首部)删除,前number个value
lrem <key> <number> <value>
将index处的值替换为value
lset <key> <index> <value>
List的数据结构为快速链表(quickList)。
在列表元素较少的情况下,会使用一块连续的内存存储,这个结构是ziplist(压缩链表)。他将所有的元素紧挨着一起存储,分配的是一块连续的内存。因为普通链表需要的附加指针空间太大,会浪费空间。比如列表里只是int类型的数据,结构还需要两个额外的指针prev和next。因此一开始,这只是使用一块连续地址存储。
当数据量比较多的时候,会变成quickList。即,多个压缩链表为节点。
功能与list类似,但是可以自动排除重复数据。
它是string类型的无序集合,底层是一个value为null的hash表。因此添加,删除,查找复杂度为O(1)。
可以看作Java里面的hashset和C++里面的unordered_set。
将一个或多个成员元素加入到集合key中,成功几个返回几个数(重复则失败)
sadd<key> <value1> <value2> …
取出集合中的所有值
smembers <key>
判断集合之中是否含有该<value>值,有为1,无为0。
sismember <key> <value>
返回该集合的元素个数
scard <key>
删除集合中的某个元素
srem <key> <value1> <value2> …
从集合中随机弹出一个值
spop <key>
随机从集合中取出n个值。但是不会从集合中删除。
srandmember <key> <n>
将集合中的一个值移动到另一个集合
smove <source> <destination> <value>
返回连个集合的交集
sinter <key1> <key2>
返回两个集合的并集
sunion <key1> <key2>
返回两个集合的差集,<key1>包含,<key2>不包含
sdiff <key1> <key2>
Set结构式通过dict字典实现的,字典则是用hash表实现的。(类似于Java 中,hashset是基于hashmap实现的)
是一个键值对集合。
是一个string类型的field和value的映射表。用于存储对象。
类似于Java中的map<String,Object>。
向hash表中加入数据
hset <key> <field> <value>
从hash表中,取出<field>中的<value>
hget <key> <field>
批量设置hash中<field>的值
hmset <key1> <field1> <value1> <field2> <value2>
查看是否存在
hexists <key> <field>
列出hash中所有的<field>
hkeys <key>
列出hash中所有的<value>
hvals <key>
为hash表key中的域值增加或减少<increment>
hincrby <key> <field> <increment>
当hash表中<field>不存在时,<field>的值设为<value>
hsetnx <key> <filed> <value>
当filed-value给的长度较短且个数较少时,使用的是ziplist
否则使用hashtable。
与set类似,无重复元素的字符串集合。
通过一个**评分(score)**的方式,从最低分到最高分的方式排序。注意,集合成员是唯一的,但是评分可以重复。
向有序集合中加入一个或多个元素
zadd <key> <score1> <value1> <scroe2> <value2>…
返回有序集合中的,下标在<start> <end>之间的元素(有 WITHSCORES 会显示评分)
zrange <key> <start> <end> [WITHSCORES]
返回score值介于<min>到<max>之间(含两端)的成员,limit offset count即是偏移数目(score从小到大)
zrangebyscore <key> <min> <max> [WITHSCORES] [limit offset count]
从大到小排列
zrevrangebyscore <key> <max> <min> [WITHSCORES] [limit offset count]
为某个值增加评分
zincrby <key> <increment> <value>
删除某个值
zrem <key> <value>
统计评分在<min> 到 <max>中,元素的个数
zcount <key> <min> <max>
返回改制在集合中的排名,从0开始
zrank <key> <value>
SortedSet(zset),一方面等价于Java中的Map<String,Double>,另一方面等价于TreeSet,内部会按照权重score进行排序,得到元素的名次以及通过范围来获取元素列表。
1.使用了hash类型,用于关联key、元素value和权重score。
2.使用了跳跃表,以此到达给value排序且能够用score的范围获取元素列表。
参考Skip List–跳表(全网最详细的跳表文章没有之一)
一般的有序链表
跳表
本身不是数据类型,而是字符串string类型。通过单独的一套命令,它可以对字符串进行位操作,来满足我们对位运算的需求。当然,只能是0或1。(若对其用stiring的命令,则会变为对应的编码格式)
可以理解为,C++中的bitset,通过下标来取值(偏移量)。
设置Bitmaps偏移量,从0开始偏移。
setbit <key> <offset> <value>
获取值
getbit <key> <offset>
统计bit位为1的数目,可不填[start end],表示范围为start到end闭区间
getcount <key> [start end]
复合操作(operation 与或非 and not xor),destkey是用来存储的key,后面则是操作的key,返回的是1的个数
bitop <operation> <destkey> <key1> [<key2> <key3> …]
用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。因此用更少的空间,表示更多的值。
基数则是不重复元素,比如{1,1,2,2,3,4,},基数就是{1,2,3,4}
注意,它不存储元素,他只是对不重复元素计数。
相关链接HyperLogLog 算法详解
添加元素
pfadd <key> <element1> [<element2> … ]
统计数目
pfcount <key>
合并多个HyperLogLog
pfmerge <destkey> <sourcekey> [<sourcekey> …]
存储地理信息。用于经纬度相关操作。
添加 多个地理信息,经度(-180~180) 纬度(-85.05112878~85.05112878) 名称
geoadd<key> <longitude> <latitude> <member> [<longitude> <latitude> <member>]
获取指定地区坐标
geopos <key> <member> [<member> …]
计算两坐标间的直线距离,[m,km,ft,mi],单位,米、千米、英里、英尺
geodist <key> <member1> <member2> [m,km,ft,mi]
以某一经纬度为中心,计算半径以内的元素,radius就是半径
georadius <key> <longitude> <latitude> <radius> m|km|ft|mi
Redis 5.0 版本新增加的数据结构。主要用于消息队列(MQ,Message Queue)。
订阅与发布模式(见后面)虽然有消息队列功能,但不能持久化。如果出现网络断开、Redis 宕机等,消息就会被丢弃。
而 Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。
Redis Stream 的结构如下所示,它有一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容
ID1、ID2、ID3…是消息队列,代表发布者发布的消息。
一般位于
/etc/redis.conf
文件大小写不敏感
单位表示,且只支持字节。
用于包含公共部分
此处是导入模块。Redis的模块采用的是动态链接库的方式,外部模块可对Redis进行功能性扩展。(此处是启动时载入,也有在运行时加载部分)
网络部分,其中bind表示限制访问IP。此处表示只能本地连接,一般将其注释即可。(同时把保护模式改为弄no)
protected-mod no
连接队列,用于记录未完成与已完成三次握手的队列。默认值是511
tcp-backlog 511
未操作连接中断时间,单位为秒,为0时永不超时
timeout 0
心跳时间,即检测连接是否活着。单位为秒。若连接已经无效,则中断。
tcp-keepalive 300
超时是指为操作,但是连接还是有效的没有中断。心跳时间是用于判断连接是否有效。就是挂机和掉线的区别。
GENERAL 一般设置
用于设置为守护进程,后台启动
daemonize yes
Redis每次操作就有一个进程号,当以守护进程进行时,进程号就会保存在里面。只有一个进程号,这样用于防止启动多个脚本。
pidfile /var/run/redis_6379
日志级别:debug(详细信息) verbose(有用信息) notice(重要信息)warning(警告信息)
loglevel notice
日志存储位置
logfile “”
库数目
database 16
SECURITY 安全设置
若要设置密码,需要取消该注释
#requirepass <password>
或者连接后用如下命令,设置密码
config set requirepass <password>
用如下命令查看密码
config get requirepass
LIMITS 限制设置
设置最大连接客户端
maxclients 10000
最大内存占用(单位为字节 byte)
maxmemory-policy <byte>
最大样本数量(一般取3~7,样本数越小越不精确,但性能消耗越小),用于LRU和TTL算法中的估算(缓存淘汰算法)。
maxmemory-samples <value>
首先在命令行中创建一个连接进程,订阅频道1
subscribe channel1
再在另一个命令行中,创建一个连接线程,发布一个消息
可以看到,返回了订阅数目
publish channel1 hello
此时另一边会发现,已经收到了消息
注意,消息没有持久化,后面订阅的无法收到前面的消息。
[1]【尚硅谷】Redis6入门到精通 超详细教程
[2]菜鸟教程-Redis
[3]Redis-官方文档
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。