redis
1. Nosql
1.1 为什么要用Nosql
-
数据量太大,一个机器放不下
-
访问量太大,服务器承受不了
-
数据库索引(B+ Tree),一个机器内存放不下
1.2 解决方案
- 垂直拆分(读写分离),优化数据结构和索引
- 网站80%的情况都是在读,每次去数据库查询十分麻烦,为了减轻数据库压力,我们采用缓存
1.3 什么是Nosql
- not only sql 不仅仅是sql
- 泛指关系型数据库,传统关系型数据库很难对付web2.0时代,尤其是超大规模的高并发社区
1.4 nosql的特点
-
最终一致性
-
不仅仅是数据
-
方便扩展(数据之间没有关系)
-
键值对存储,列存储,文档存储,图形数据库
-
没有固定的查询语言(关系型数据库有固定的查询语言)
-
数据类型是多样型的(不需要事先设计数据库,随取随用)
-
大数据量高性能(redis一秒读写8万次,Nosql是一种细粒度的缓存性能会比较高 )
真正在公司:Nosql+RDBMS(非关系型数据库与关系型数据库结合使用)
1.5 大数据时代
大数据时代的3V:主要是描述问题的
- 海量Volume
- 多样Variety
- 实时Velocity
大数据时代的3高:主要是对程序的要求 - 高并发
- 高可扩
- 高性能
2.业务分析
- 商品的交易(第三方应用接口)
- 商品的描述评论(文字较多,采用文档型数据库MongoDB)
- 商品关键字(搜索功能:Isearch:阿里第一个程序员:多隆)
- 图片(分布式文件系统:FastDFS,阿里oss/TFS,Hadoop HDFS)
- 商品基本信息:名称、价格、商家信息(阿里内部修改版的Mysql)
- 商品热门的波段信息(秒杀:内存数据库 redis、Tair、memecache)
3.Nosql的四大分类
3.1 KV键值对
- 新浪:redis
- 美团:redis+tair
- 阿里、百度:redis+memecache
3.2 文档型数据库(bson格式和json一样)
- MongoDB是一个基于分布式文件存储的数据库,C++编写用来处理大量的文档
- MongoDB是一个介于关系型数据库与非关系型数据库的中间产品,是非关系型数据库中功能最丰富,最像关系型数据库的
3.3 列存储数据库
- Hbase
- 分布式文件系统
3.4 图关系数据库
- Neo4j,Infogrid
- 不是存的图形,是存放的关系,例如朋友圈社交关系,推荐系统
4. redis入门
4.1 redis是什么?
- redis(remote dictionary server:远程字典服务)
- 开源的使用C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
4.2 redis能干嘛?
- 发布订阅系统
- 地图信息分析
- 计时器、计数器(浏览量)
- 效率高,可以用于高速缓存
- 内存存储、持久化,内存中时断电即失,所以持久化很重要(rdb,aof)
5. 安装redis
- linux原生式安装
- 宝塔面板安装(我用的)
- docker安装(还没学,看评论他们用这个也多)
宝塔无脑安装真的很香
5.1 测试redis性能
- 用xshell连接阿里云服务器
- 进入根目录下的bin 连接6379端口:**redis-cli -p **6379(确保能够连接的上)
- 进入cd /usr/local/bin下执行测试命令:redis-benchmark -h localhost -p 6379 -c 100 -n 100000
6. redis基础知识
6.1 redis的基本命令
-
set name weishiqian(set命令创建)
-
get name(获取刚才创建的信息)
-
keys *(查看当前数据库所有的key)
-
flushdb(清空当前库)flushall(清空所有)
-
exists name(判断某个key是否存在)
-
move name 1(移动某个key值到另一个库)
-
del name(删除某一个key值)
-
expire name 10(设置key的过期时间为10秒)
-
ttl name(查看剩余的过期时间还有多少秒)
-
type name(查看不同的数据类型)
-
redis有16个数据库,默认使用第0个数据库,通过select可以修改数据库,dbsize查看大小
redis官网可以查看命令帮助文档
6.2 redis线程问题
redis是一个基于内存的数据库, 6.0以后引入了多线程
- 为什么redis一开始使用单线程(单线程的好处)?
redis基于内存使用I/O多路复用技术,单线程速度很快,又保证了多线程特点,所以没必要使用多线程 - 为什么 Redis 在 6.0 之后加入了多线程(在某些情况下,单线程有缺点,多线程可以解决)?
- 现在引入是因为在某些操作要优化,比如删除操作,对于一些大键值对的删除操作,通过多线程非阻塞地释放内存空间也能减少对 Redis 主线程阻塞的时间,提高执行的效率,因此引入了多线程。
7. redis的五大数据类型
- 数据库,缓存,消息三大功能
- 字符串、哈希表、列表、集合、有序集合、位图等数据类型
7.1 String(字符串类型)
-
append:追加字符串,如果key不存在就相当于setkey
-
strlen:获取字符串的长度
-
incr/decr:增加/减少
-
incrby/decrby:按照指定步长增加减少(计数器:文章浏览量)
-
getrange:获取指定范围内的字符串
-
setrange:设置指定范围内的字符串
-
setex:设置过期时间
-
setnx:不存在再设置(在分布式锁中应用)
-
mset:批量设置key值
-
mget:批量获取key值
-
msetnx:原子性操作,要么一起成功,要么一起失败
-
设置user对象:mset user:1:name weishiqian user:1:age 21 ,mget user:1:name user:1:age
-
getset:先get再set(更新操作)
7.2 List(列表)
值可以重复
- 在redis里面我们可以把list完成栈(先进后出),队列(先进先出),阻塞队列
- lpush:将一个值或多个值插入到列表头部(左)
- rpush:将一个或者多个值插入到列表尾部(右)
- lrange:查看指定范围的value值(0,-1则是查看全部)
- lindex:通过下标获取值
- llen:返回列表的长度
- lrem:移除指定个数的value值
- ltrim:通过下标截取指定长度的内容
- rpoplpush:移除列表的最后一个元素,并将他移动到新的列表当中
- lset:将列表中指定下标的值替换为另外一个值(更新操作)
- linsert:将某个value插入到列表中某个元素的前面或者后面
7.3 Set(集合)
set:无序不重复集合
-
sadd:set集合中添加元素(可以批量)
-
smembers:查看set里面的所有值
-
sismember:判断某一个值是不是在set集合中
-
scard:获取set集合中元素的个数
-
srem:移除set集合中的指定元素
-
spandmember:随机抽取指定个数的元素
-
spop:随机删除set集合中的元素
-
smove:将一个指定的值,移动到另外一个set集合中
-
sdiff:两个set集合的差集
-
sinter:两个set集合的交集(共同好友)
-
sunion:两个set集合的并集(共同关注)
7.4 Hash(哈希)
map集合,key-map(key-value),本质和string类型没有太大区别
-
hset:set一个具体的key-value值
-
hget:获取一个字段值
-
hmset:set多个key-value值
-
hmget:批量获取指定值
-
hgetall:获取所有的值
-
hdel:删除hash指定的key字段,对应的value也就消失了
-
hlen:获取hash表的字段数量
-
hexists:判断hash中的指定字段是否存在
-
hkeys:只获取所有的field
-
hvals:只获取所有的value
-
hincrby:指定增量递增
-
hdecrby:指定减量递减
-
hsetnx:如果不存在则可以设置(分布式锁 )
hash存放经常变更的信息(用户信息),hash更适合于对象的存储,string更加适合字符串存储
7.5 Zset(有序集合)
在set的基础上增加了一个值,set k1 v1,zset k1 score1 v1
- zadd:添加一个值(也可以批量添加)
- zrange:遍历指定范围的值
- zrangebyscore salary -inf +inf:按照从小到大排序
- zrevrange salary 0 -1:按照从大到小排序
- zrem:移除某个元素
- zcard:获取有序集合中的个数
- zcount:获取指定区间的成员数量
班级成绩表,工资表排序,排行榜应用实现
8. 三种特殊数据类型
8.1 geospatial地理位置
朋友的定位,附近的人,打车距离计算
- 只有6个命令:
- geoadd:添加地理位置,名称,经度,纬度(一般会下载城市数据通过java程序一次性导入)
- gaopos:查询具体位置的经度纬度(坐标值)
- gaodist:返回两个地点之间的直线距离
- gaoradius:获取附近的人的地址定位(以坐标为中心)
- georadiusbymember:获取附近的地址位置(以城市为中心)
geo的底层实现就是zset,zset的查看命令(zrange),移除命令(zrem)都可以使用
8.2 Hyperloglog(基数统计算法)
什么是基数? 一个数据集内的不重复元素
- 网站的UV(一个人访问一个网站多次,但还是算作一个人)
- pfadd:创建元素
- pfcount:统计基数的数量
- pfmerge:合并两组元素
如果允许容错,那么一定使用Hyperloglog
如果不允许容错,就使用set集合
8.3 Bitmap(位图)
位存储:只有两个状态
- 统计用户信息,登录,未登录,打卡,未打卡(只有两个状态的都可以使用Bitmaps)
- setbit:记录打卡的状态
- getbit:查看某一天是否打卡
- bitcount:查看打卡的天数