适用场景:
1. 存储大量的非结构化和半结构化数据
2. 需要能够迅速水平扩展容量的db
3. 高性能的实时数据插入/更新
不适用:
1. 需要事务控制的场景,比如银行和会计系统
2. 需要复杂SQL语句的场景
skip = ps * (pn - 1)
coll.find(query_filter).sort(sort).limit(ps).skip(skip)
db.login_info.aggregate([
{
'$match': { #先查询出满足条件的数据
'user.login_time':{
'$gte':-1,
'$lte':1555555555555
}
}
},
{
'$project': # 对某个字段进行处理
{'hour':{ #dateToString转换只接受毫秒时间戳
'$multiply':['$user.login_time',1000]
}
}
},
{ # 再处理
'$project': {'hour':{'$dateToString': { #format 提取时间单位,具体格式参见底下的图
format:'%H',
date: {'$add': [new Date(0),'$hour']}
}
}
}
},
{ #然后聚合
'$group': {'_id':'$hour','count':{'$sum': 1}}
},
{ #再对需要输出的字段进行整理
'$project':{'_id':0,'hour':'$_id','count':'$count' }
}
])
MongoDB不支持事务和锁机制,同时也提高了它的性能。
库名和集合名以点拼接起来的字符串。
也就是热点数据的存储,通常是查询多,删改少的数据。redis性能远高于mysql
比如对点击数、点赞数的统计,这种场景对数据库操作频繁,对速率要求很高(毫秒级别),mysql不可行。
比如统计千万或上亿级别用户的在线状态,如果为每个用户建立一个key,那消耗的内存就太恐怖了,
用mysql更不用考虑了,mysql完全不适用大数据处理。
而redis支持bitmap操作,可以创建一个key,value是str,redis中一个str的最大长度是512MB,
对应2^32-1个比特位,支持42亿个用户仅需512MB内存,然后使用offset作为一个唯一用户标识,
value为0或1标识用户的在线与否。
比如对分布式服务中的某一个操作做并发限制,就可以设计让一个操作执行前往redis中
执行set k1 v1 nx=true ex=10, 如果set成功,标识该操作可以执行,否则就要等待其他操作完成后再执行。
执行完后delete这个key。ex参数用于防止死锁。
使用List结构配合 lpush + rpop操作实现队列。
使用zset结构可以轻松是实现排行榜场景。
小结:这些场景多利用redis的数据结构和内存高速读写的优势,mysql无法比拟。
主要命令:
MULTI: 开启事务
EXEC:顺序执行事务队列中的命令
DISCARD:放弃事务
WATCH:监视一个key的,若改动前该key变动了,事务执行中断。
UNWATCH:取消对所有key的监视
几个特性:
1. 命令进入事务队列时,会检查命令拼写的正确性,但不会检查命令用法的正确性。
2. 单条命令具有原子性,单个事务不具有完整的原子性(当事务后面部分的命令用法错误时,前面有效的命令仍然执行成功;而当所有事务内命令用法都正确时,可以利用watch命令实现原子性,即可回滚)
依次输入(假设key_1已存在):
watch key_1 #必须在事务开始前监视要改动的key
multi
incr key_1
exec #若key被改动,事务执行失败,key不会加一
使用互斥锁,即改值的顺序变为: 获得锁-->改值-->释放锁。(这是悲观锁模型)
很明显,满了就无法再写入新key,那怎么解决呢?
规则有六种,重点说LRU相关的两条。
1. volatile-lru 使用LRU算法删除一个键(只对设置了生存时间的键)
2. allkeys-lru 使用LRU算法删除一个键
LRU:Least RecentlyUsed 最近最少使用算法,即删除最近最少使用的key。
可能需要你手写LRU算法。
4.1 mem数据类型仅支持字符串
4.2 mem是多线程服务模式,redis是单线程模式。
4.3 mem不支持持久化,redis支持。
5.1 键值存储结构,大部分操作的时间复杂度为O(1),这点决定了查找不需要什么CPU计算。(但是LSET/HGETALL这些是O(n)复杂度操作,因为单线程,它会阻塞别的操作,要慎用)
5.2 单线程没有多线程多进程带来的上下文切换以及同步问题,同步会导致很大的性能损耗
5.3 使用的多路IO复用模型(epoll),这是一种高性能IO处理模型
5.4 如何利用多核CPU:一台服务器上启动多个实例(等于CPU个数),每个实例绑定一个CPU,不让操作系统调度选择哪个CPU,这样就避免了切换开销。
a.手动执行redis命令:bgrewriteaof, 执行后,AOF文件重写操作会被预定,待redis空闲时会执行。
b.修改配置自动触发重写操作。
#代表当前AOF文件空间和上次重写后AOF空间的比值。
auto-aof-rewrite-percentage 100
#AOP超过10m就开始收缩
auto-aof-rewrite-min-size 10mb
说明:当AOF文件第一次达到10mb时就开始进行文件重写,下一次重写的文件大小是上一次的一倍即20mb,再下次就是40mb。