HyperLogLog
基于HyperLogLog算法:极小的空间完成独立数量统计,极小内存实现去重
- 爬虫去重
- 黑白名单
- 垃圾邮件过滤
pfadd urls "www.baidu.com" "www.cnblogs.com" "www.lqz.com"
pfcount urls
pfadd urls 值 # 返回0表示在,返回1 表示不在
# 总结
百万级别独立用户统计(用户id可以不是数字),万条数据只占15k
错误率 0.81%
无法取出单条数据,只能统计个数
geo
# GEO(地理信息定位):存储经纬度,计算两地距离,范围等
# 经纬度如何获取?
-不是后端做的
-手机端---》手机有定位--》申请了定位---》手机端能拿到经纬度---》提供接口--->提交到后端
-web端---》js获取经纬度---》提供接口---》提交到后端
# 后端只需要存储
geoadd key longitude latitude member #增加地理位置信息
geoadd cities:locations 116.28 39.55 beijing #把北京地理信息天津到cities:locations中
geoadd cities:locations 117.12 39.08 tianjin
geoadd cities:locations 114.29 38.02 shijiazhuang
geoadd cities:locations 118.01 39.38 tangshan
geoadd cities:locations 115.29 38.51 baoding
# 统计两个经纬度距离
geodist cities:locations beijing baoding km
# 统计北京方圆 100公里内的城市
georadiusbymember cities:locations beijing 100 km
# 本质数据类型是有序集合
持久化
# 把redis数据从内存保存到硬盘上的过程称之为持久化
把数据保存在硬盘上永久存储 过程叫持久化
# 所有的数据库,持久化方案
快照:某时某刻数据的一个完成备份
-mysql的Dump: mysqldump -uroot -p123456 -luffy >/data/mysqlDump/mydb.sql
-redis的RDB:
写日志:任何操作记录日志,要恢复数据,只要把日志重新走一遍即可
-mysql的 Binlog
-Redis的 AOF
# redis 主要的两种持久化方案
- rdb:快照方案
- aof:日志方案
RDB 持久化方案
# 三种方案触发rdb
### 方案一:同步方案--》敲save命令---》会阻塞redis--》如果数据量很大--》会导致其他命令都执行不了
reids客户端敲一个命令 : save
### 方案二:异步方案
reids客户端敲一个命令 : bgsave
-开启一个异步线程进行持久化,不会阻塞redis操作线程
### 方案三:配置文件方案---》只要符合条件,会自动生成rdb文件
save 900 1
save 300 10
save 60 10000
如果60s中改变了1w条数据,自动生成rdb
如果300s中改变了10条数据,自动生成rdb
如果900s中改变了1条数据,自动生成rdb
## 演示()
save 60 2 # 60s内改了2条数据,就做rdb的持久化
dbfilename dump-6379.rdb #以端口号作为文件名,可能一台机器上很多reids,不会乱
dir /bigdiskpath #保存路径放到一个大硬盘位置目录
stop-writes-on-bgsave-error yes #出现错误停止
rdbcompression yes #压缩
rdbchecksum yes #校验
------------------------
save 60 2
dbfilename dump-6379.rdb
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
# 只要在工作目录下有rdb文件,redis重启,就会加载,整个load到内存中
aof持久化
# RDB问题
耗时,耗性能,不可控,可能会丢失数据
# aof 方案
客户端每写入一条命令,都记录一条日志,放到日志文件中,如果出现宕机,可以将数据完全恢复
# AOF的三种策略
# 日志不是直接写到硬盘上,而是先放在缓冲区,缓冲区根据一些策略,写到硬盘上
always:redis–》写命令刷新的缓冲区—》每条命令fsync到硬盘—》AOF文件
everysec(默认值):redis——》写命令刷新的缓冲区—》每秒把缓冲区fsync到硬盘–》AOF文件
no:redis——》写命令刷新的缓冲区—》操作系统决定,缓冲区fsync到硬盘–》AOF文件
# AOF 重写 随着命令的逐步写入,并发量的变大, AOF文件会越来越大,通过AOF重写来解决该问题
set hello world
set hello java set hello hehe
set hello hehe
incr counter
incr counter ======>>> incryby counter 2
rpush mylist a
rpush mylist b rpush myslist a b c
rpush mylist c
过期数据
# 本质就是把过期的,无用的,重复的,可以优化的命令,来优化 这样可以减少磁盘占用量,加速恢复速度
# 咱们只需要做好配置,触发aof重写后,redis会自动开启aof重写,优化 日志
# 配置
auto-aof-rewrite-min-size AOF文件重写需要尺寸
auto-aof-rewrite-percentage AOF文件增长率
# aof持久化方案 --配置方案
appendonly yes #将该选项设置为yes,打开
appendfilename "appendonly-6379.aof" #文件保存的名字
appendfsync everysec #采用第二种策略
no-appendfsync-on-rewrite yes #在aof重写的时候,是否要做aof的append操作,因为aof重写消耗性能,磁盘消耗,正常aof写磁盘有一定的冲突,这段期间的数据,允许丢失
appendonly yes
appendfilename "appendonly-6379.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes
## aof和rdb能同时开启吗?
完全可以
# 你们用了那种?
取决于公司业务:对数据要求高,不允许丢失---》就必须使用aof方案
如果允许丢失,就使用rdb方案
混合持久化
# 混合持久化原理
在开启混合持久化的情况下,AOF 重写时会把 Redis 的持久化数据,以 RDB 的格式写入到 AOF 文件的开头,之后的数据再以 AOF 的格式化追加的文件的末尾
二进制
日志4
日志5
# 目的是为了加快恢复
# 配置是:
appendonly yes
appendfilename "appendonly-6379.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes
aof-use-rdb-preamble yes #开启了混合持久化
主从复制
# 单实例redis存在问题
机器故障;容量瓶颈;QPS瓶颈
QPS瓶颈:主从 一主一从,写操作都写到主库,读操作从从库读
容量瓶颈:集群
机器故障:一主两从,哨兵故障转义
# 主从复制是什么?
一主一从,一主多从
作用1 :做读写分离
作用2 :做数据副本
作用3:提高并发量
一个master可以有多个slave
一个slave只能有一个master
数据流向是单向的,从master到slave
# 主从复制原理
1. 副本库(从库)通过slaveof 127.0.0.1 6379命令,连接主库,并发送SYNC给主库
2. 主库收到SYNC,会立即触发BGSAVE,后台保存RDB,发送给副本库
3. 副本库接收后会应用RDB快照
4. 主库会陆续将中间产生的新的操作,保存并发送给副本库
5. 到此,我们主复制集就正常工作了
6. 再此以后,主库只要发生新的操作,都会以命令传播的形式自动发送给副本库.
7. 所有复制相关信息,从info信息中都可以查到.即使重启任何节点,他的主从关系依然都在.
8. 如果发生主从关系断开时,从库数据没有任何损坏,在下次重连之后,从库发送PSYNC给主库
9. 主库只会将从库缺失部分的数据同步给从库应用,达到快速恢复主从的目的
# 主库是否要开启持久化
如果不开,有可能,主库重启操作,造成所有主从数据丢失!
#主从搭建---准备
-启动两个redis-server的进程---》模拟两台机器的两个redis进程
-准备两个配置文件
daemonize yes
bind 0.0.0.0
pidfile "/var/run/redis.pid"
port 6379
dir "/root/redis-7.2.4/data"
logfile "6379.log"
appendonly yes
appendfilename "appendonly-6379.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes
aof-use-rdb-preamble yes
-------------------------------
daemonize yes
bind 0.0.0.0
port 6380
dir "/root/redis-7.2.4/data1"
logfile "6380.log"
appendonly yes
appendfilename "appendonly-6380.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes
aof-use-rdb-preamble yes
-启动两个进程
reids-server ./redis.conf
reids-server ./redis_6380.conf
# 主从搭建---》方式一
-6379是主,6380是从
-链接到从库,执行:slaveof 127.0.0.1 6379
-主从既能查,又能写
-从库只能查
-断开主从关系:slaveof no one #取消复制,不会把之前的数据清除
# 主从搭建---》方式二 通过配置文件
-从库辅助配置(可以不配)
min-slaves-to-write 1
min-slaves-max-lag 3
#在从服务器的数量少于1个,或者三个从服务器的延迟(lag)值都大于或等于3秒时,主服务器将拒绝执行写命令
-核心配置通过配置文件
slaveof 127.0.0.1 6379
slave-read-only yes
# info 命令可以查看主从关系
python操作
# 原生操作
-主:10.0.0.111::6379
-从:10.0.0.111::6380
-从:10.0.0.111::6381
conn=10.0.0.111::6379
以后只 set mset rpush
conn1=10.0.0.111::6380
conn2=10.0.0.111::6381
只要是查询,随机从conn1和conn2中出
10.0.0.111
# django 的缓存
第一步:redis的配置中配置多个redis
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://localhost:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
"redis1": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://localhost:6379/0",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
第二步:使用
from django.core.cache import caches
caches['redis1'].set("name",'lqz') # 写
res=caches['default'].get('name') # 读