Redis(Remote Dictionary Server ),即远程字典服务。
是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
1.官网下载redis
2.解压安装包
tar -zxvf redis***
3.基本环境安装
yum install gcc-c++
#进入到redis目录下执行
make
make install
5.将redis的配置文件redis.conf 复制到程序安装目录下/usr/local/bin/kcongif下
6.设置后台启动,修改vim redis.conf配置文件
7.通过指定的配置文件启动redis服务
8.使用redis-cli连接指定的端口号测试,默认是6379
9.查看redis进程是否开启
ps -ef|grep redis
10.关闭redis服务
shutdown
keys * :查看当前数据库中所有的key
flushdb:清空当前数据库中的键值对
flushall :清空所有数据库的键值对
redis默认有16个数据库
redis每秒可读11万条数据,每秒可写8万条数据
使用select n可以切换到指定的数据库
dbsize可以查看当前数据库的大小,数据库的大小和key数量有关
不同数据库之间,数据是不能互通的,即在数据库2中,无法直接访问数据库1中的key值
redis是单线程的,且是基于内存操作的
redis的性能是瓶颈是基于机器内存和带宽的,与cpu的性能无关
在redis中无论什么数据类型,在数据库中都是以key-value形式保存,通过进行对Redis-key的操作,来完成对数据库中数据的操作.
- reids的set是string类型的无序集合,因为集合成员是唯一的,因此不能出现重复的元素
Redis中集合是通过哈希表实现的,所以添加、删除、查找的复杂度都是O(1)
集合最大成员数2^32 -1
redis hash是一个是string 类型的field和value的映射表,Hash适合用于存储对象。
set是一种简化的hash,只要变动key,value的值就会默认的变动
常用的命令
命令 | 描述 |
---|---|
hset key field value | 将哈希表 key 中的字段 field 的值设为 value 。重复设置同一个field会覆盖,返回0 |
HMSET key field1 value1 [field2 value2…] | 同时将多个 field-value (域-值)对设置到哈希表 key 中。 |
HSETNX key field value | 只有当字段field不存在时,设置该字段 |
HSETNX key field value | 查看当前hash表中,指定的字段值是否存在 |
HGET key field value | 获取存储在hash表中的字段值 |
HMGET key field1 | 取所有给定字段的值 |
HDEL key field1 | 删除哈希表key中一个/多个field字段 |
HINCRBY key field n | 为哈希表 key 中的指定字段的整数值加上增量n |
HLEN key | 获取哈希表中字段的数量 |
应用案例:
a{1,2,3,4,4,5,6,7,8}
b{3,4,5,6,6,8.4,7}
a集合基数(不重复元素的个数)=8
b集合基数(不重复元素的个数)=5
pfadd key element #添加指定元素到 HyperLogLog中
PFCOUNT key [key ...] #返回给定 HyperLogLog 的基数估算值
genadd # 添加地理位置(地理经纬度)
127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai
(integer) 1
geopos # 获取指定城市的经度和纬度
GEOPOS china:city beijing chongqi
1) 1) "116.39999896287918091"
geodis # 获取两人之间的距离
GEODIST china:city beijing shanghai km
georadius # 以给定的经纬度为中心, 找出某一半径内的元素
GEODIST china:city beijing shanghai km # 查看上海到北京的直线距离
"1067.3788"
georadlusbymember # 找出位于指定元素周围的其他元素!
GEORADIUSBYMEMBER china:city beijing 1000 km
1) "beijing"
2) "xian"
知识扩展:
geo的底层原理是zset,可以用zset命令操作geo
bitmap就是通过最小的单位bit来进行0或者1的设置,表示某个元素对应的值或者状态。
setBit key 0 1 # 给一个指定key的值得第offset位 赋值为value。
getbit key offset # 返回一个指定key的二进制信息
MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务相关的命令。事务可以一次执行多个命令, 并且带有以下两个重要的保证:
事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务中所有的命令操作都是序列化、顺序执行
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379(TX)> set key1 v1 #命令入队
QUEUED
127.0.0.1:6379(TX)> set key2 v2
QUEUED
127.0.0.1:6379(TX)> set key3 v3
QUEUED
127.0.0.1:6379(TX)> get key2
QUEUED
127.0.0.1:6379(TX)> set key4 v4
QUEUED
127.0.0.1:6379(TX)> exec #执行事务
1) OK
2) OK
3) OK
4) "v2"
5) OK
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI #当前未开启事务
执行discard时,事务将会被阻断不被执行
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379(TX)> set k 2 #命令入队
QUEUED
127.0.0.1:6379(TX)> set k1 3
QUEUED
127.0.0.1:6379(TX)> set k2 4
QUEUED
127.0.0.1:6379(TX)> DISCARD #放弃事务
OK
127.0.0.1:6379> get k2
(nil)
127.0.0.1:6379> exec #执行事务出错
(error) ERR EXEC without MULTI
127.0.0.1:6379>
编译时错误:代码语法错误,所有的命令都不会执行
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379(TX)> set k 1 #命令入队
QUEUED
127.0.0.1:6379(TX)> set k1 2
QUEUED
127.0.0.1:6379(TX)> error #执行一个错误的命令
(error) ERR unknown command `error`, with args beginning with:
127.0.0.1:6379(TX)> set k3 4
QUEUED
127.0.0.1:6379(TX)> exec # 执行事务出现异常
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379>
运行时异常,代码逻辑错误,其他命令正常执行
所以不保证事务原子性操作
127.0.0.1:6379> multi#开启事务
OK
127.0.0.1:6379(TX)> set k1 v1 #命令入队
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> incr k1 #对字符串进行自增操作(该命令逻辑错误)
QUEUED
127.0.0.1:6379(TX)> get k2
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK
3) OK
4) (error) ERR value is not an integer or out of range #命令报错
5) "v2"
#该结果说明 redis单条指令保证原子性操作,但是redis事务不能保证原子性
使用watch key
监控指定数据,相当于乐观锁加锁。
基于单线程正常执行
127.0.0.1:6379> set money 100 #设置Money 100
OK
127.0.0.1:6379> set use 0 #设置use 0
OK
127.0.0.1:6379> watch money #监视money 上锁
OK
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379(TX)> decrby money 30
QUEUED
127.0.0.1:6379(TX)> incrby use 30
QUEUED
127.0.0.1:6379(TX)> exec #监视数据是否被修改
1) (integer) 70
2) (integer) 30
127.0.0.1:6379>
测试多线程修改值,使用watch可以当做redis的乐观锁操作
# 线程1
27.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set use 0
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> decrby money 50
QUEUED
127.0.0.1:6379(TX)> incrby use 50
QUEUED
#开启线程2
[root@gitShile bin]# redis-server kconfig/redis.conf
[root@gitShile bin]# redis-cli -p 6379
127.0.0.1:6379> incrby money 500
(integer) 600
127.0.0.1:6379>
#继续操作线程1
127.0.0.1:6379(TX)> exec #执行事务
(nil)
127.0.0.1:6379> get money
"600"
127.0.0.1:6379> get use
"0"
在指定的时间间隔内,将内存的数据集快照(Snapshot)写入磁盘,它恢复时是将快照文件写入到内存中。
rbd保存的文件以dump.rbd二进制的形式快照中进行配置的
redis会单独创建(folk)一个进程来实现持久化,将数据写入到一个临时文件中,待持久化结束后,再用这个临时文件替换上次持久化好的文件。
fork进程的时候,会占用一定的内容空间
需要一定的时间间隔进程操作!如果redis意外宕机了,这个最后一次修改数据就没有的了!
以日志的形式记录redis每一个写操作,将redis执行的过程记录下来(不追加读操作),只需追加不可改写文件
redis启动之后会读取appendonly.aof文件来实现重新恢复数据,完成恢复数据的工作。默认不开启,需要将redis.conf中的appendonly no改为yes启动Redis。
appendfsync always:#每修改同步,每一次发生数据变更都会持久化到磁盘上,性能较差,但数据完整性较好。
appendfsync everysec: #每秒同步,每秒内记录操作,异步操作,如果一秒内宕机,有数据丢失。
appendfsync no:#不同步。
重启Redis时,如果dump.rdb与appendfsync.aof同时都存在时,Redis会自动读取appendfsync.aof文件,通过该文件中对数据库的日志操作,来实现数据的恢复。当然如果该文件被破坏,我们可以通过redis-check-aof工具来修复,如redis-check-aof --fix能修复破损的appendfsync.aof文件,当然如果dump.rdb文件有破损,我们也可以用redis-check-rdb工具来修复,如果appendfsync.aof文件破损了,是启动不客户端的,也就是无法完成数据的恢复。
学习资源来自:https://www.bilibili.com/video/BV1S54y1R7SB?t=348&p=36
redis官网:redis中文官方网站
redis面试高频问题:redis面试题
狂神说redis:狂神说redis.