关系型数据库的缺点:
- 性能瓶颈:磁盘IO性能低下
- 扩展瓶颈:数据关系复杂,扩展性差,不利于大规模集群
解决思路:
- 降低磁盘IO次数,越低越好 --内存存储
- 去除数据间关系,越简单越好 --不存关系,只存数据
NoSQL
即Not-Only-SQL(泛指非关系型数据库),作为关系型数据库的补充 作用:应对基于海量用户和海量数据前提下的数据处理问题 特征:
- 可扩容,可伸缩
- 大数据量下高性能
- 灵活的数据模型
- 高可用
常见NoSQL数据库:
- Redis
- HBase
- MongoDB
- memcache
Redis
Redis(REname Dictionary Server)是用C语言开发的一个开源的高性能键值对(Key-value)数据库 特征:
- 数据间没有必然的关联关系
- 内部采用单线程机制进行工作
- 高性能(读110000次/s,写81000次/s)
- 多数据类型支持
- 持久化支持,可以进行数据容灾恢复
应用:
- 为热点数据加速查询,如热点商品、热点新闻等
- 任务队列,如秒杀、抢购等
- 即时信息查询,如公交到站信息、在线人数等
- 时效性信息控制,如验证码、投票等
- 分布式数据共享,如分布式集群架构中session分离
- 消息队列
- 分布式锁
在Linux下安装redis
安装中需要注意几点:
- 在linux下安装redis,默认会安装到/usr/local/bin中
- 在redis解压文件中有一个redis.config是redis配置文件,很重要
- redis默认不是后台启动的,需要修改配置文件redis.config中的daemonize属性,默认是no,改为yes后,redis将在后台启动
- 通过制定的配置文件启动服务 redis-server redis.config
- 使用rdis客户端进行连接:redis-cli -p 6379(redis默认端口号6379)
- 关闭redis服务:shutdown;退出redis连接:exit
性能测试
在redis安装目录中有一个redis-benchmark是官方自带的性能测试工具
选项 | 描述 | 默认值 |
---|
-h | 指定服务器主机名 | 127.0.0.1 | -p | 指定服务器端口 | 6379 | -s | 指定服务器socket | | -c | 指定并发连接数 | 60 | -n | 指定请求数 | 10000 | -d | 以字节的形式指定set/get值得数据大小 | 2 | -k | 1=keep alive 0=reconnect | 1 | -r | set/get/incr使用随机key、SADD使用随机值 | |
… #测试:100个并发连接 100000请求 redis-benchmark -h localhost -p 6379 -c 100 -n 100000
基础的知识
redis默认有16个数据库,在redis.config中有个database属性,默认值为16,默认使用0数据库 可以使用select进行切换数据库
select 3
keys *
flushdb
flushall
Redis是单线程的! 官方表示,Redis是基于内存操作,CPU不是Redis性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽,既然可以使用单线程实现,就使用单线程了,所以redis就是单线程的
Redis为什么单线程还那么快?
- 误区1:高性能的服务器一定是多线程的?
- 误区2:多线程一定比单线程效率高?
核心:redis是将所有的数据全部放在内存中的,所以说使用单线程去操作效率就是最高的,多线程(CPU上下文切换:耗时的操作),对于内存系统来说,如果没有上下文切换,效率就是最高的。多次读且都是在一个CPU上的,在内存情况下,这个就是最佳的方案!
Redis五大数据类型
- String字符串
- List列表
- Set集合
- Zset有序集合
- Hash散列
Redis-key操作:
keys *
set name zhangsan
get name
type name
exists name
expire name 10
ttl name
move name 1
String类型:
set key1 "v1"
get key1
append key1 "hello"
get key1
strlen key1
getrange key1 0 3
getrange key1 0 -1
set key2 "abcdefg"
setrange key2 1 xx
setex(set with expire)
setex key3 30 "hello"
setnx(set if not exist)
setnx mykey "redis"
setnx mykey "MongoDB"
getset db redis
mset k1 v1 k2 v2 k3 v3
mget k1 k2 k3
msetnx k1 v1 k4 v4
set views 0
incr views
decr views
incrby views 10
decrby views 5
String类似的使用场景:value除了是字符串,还可以是数字
List类型: 在redis里面,list可以作为栈、队列、阻塞队列等 所有的list命令都是以l开头的
lpush list one
lpush list two
lpush list three
lrange list 0 -1
lrange list 0 1
rpush list right
llen list
lindex list 0
lpop list
rpop list
flushdb
lpush list one
lpush list two
lpush list three
lpush list three
lrem list 1 one
lrem list 2 three
flushdb
rpush mylist "hello0"
rpush mylist "hello1"
rpush mylist "hello2"
rpush mylist "hello3"
ltrim mylist 1 2
rpoplpush 旧列表名 新列表名
lset 列表名 下标位置 新元素
linsert 列表名 before|after "指定字符串" "新元素"
list:
- list实际上是一个链表 before Node after,left和right都可以插入值
- 如果key不存在,创建新的链表
- 如果key存在,新增内容
- 如果移除了所有值,相当于空链表,也就代表不存在
- 在两边插入或改动值,效率最高;中间元素,相对来说效率低一点
可以使用作为消息队列
set类型: set中的值是不能重复的,set的命令都是以s开头的
sadd 集合名 元素值
smembers 集合名
sismember 集合名 元素值
scard 集合名
srem 集合名 元素值
spop 集合名
srandmember 集合名 个数
smove 旧集合名 新集合名 元素
sdiff 集合1 集合2
sinter 集合1 集合2
sunion 集合1 集合2
set集合可以在微博,共同关注、共同爱好等上使用
Hash类型: Map集合,key-map,值是一个map集合,本质和String类型没有太大区别,还是一个简单的key-value hash命令以h开头
hset 集合名 key value
hget 集合名 key
hmset 集合名 key1 value1 key2 value2
mget 集合名 key1 key2
hgetall 集合名
hdel 集合名 key
hlen 集合名
hexiste 集合名 key
hkeys 集合名
hvals 集合名
hsetnx 集合名 key value
hash:
- 变更的数据,user name age,尤其是用户信息之类的,经常变动的信息,hash更适合对象的存储,String更适合字符串存储
Zset类型: 在set的基础上增加了一个值,zset命令以z开头
zadd 集合名 排序标志 元素
zrange 集合名 0 -1
zrangebyscore 集合名 -inf +inf
zreveange 集合名 0 -1
rangebyscore 集合名 -inf +inf withscores
zrem 集合名 元素
zcard 集合名
zcount 集合名 排序标志1 排序标志2
set能做的zset都可以,相当于set集合能排序
三种特殊数据类型
geospatial地理位置: 朋友的定位、附近的人、打车距离计算 Redis的Geo在3.2版本推出的,这个功能可以推算地理位置的信息、两地之间的距离、方圆几里的人 只有6个命令:
- gotadd 添加地理位置 规则:两级无法直接添加,一般可以下载城市数据,通过java程序一次性导入,参数key值(经度、纬度、名称)有效的经度从-180度到180度;有效的纬度从-85.05112878度到85.05112878度,当坐标超过上述范围后,该命令会返回一个错误
- geodist 两人 / 地之间的距离 单位:m 米;km 千米; mi 英里;ft 英尺
- geohash 返回一个或多个位置元素的Geohash表示
- geopos 获取指定城市的经度和纬度
- georadius 以给定的经度和纬度为中心,找出某一半径内的元素
- georadiusbymember 找出位于指定元素周围的其他元素
注意: Geo底层的实现原理其实就是Zset,我们可以使用Zset命令来操作geo
Hyperloglog基数统计算法: Redis在2.8.9版本更新了Hyperloglog数据结构 Hyperloglog是用来做基数统计的算法 优点:占用的内存是固定的,2^64不同的元素的技术,只需要费12KB内存,如果要从内存角度来比较的话Hyperloglog是首选(有0.81%错误率) 命令以P开头
- pfadd 集合名 元素… 添加元素
- pfcount 集合名 计数
- pfmerge 得到的集合 目标集合1 目标集合2 获取两个目标集合的并集(去重)
如果允许容错,那么一定使用Hyperloglog! 如果不允许容错,那么就使用set或自己需要的数据类型即可
Bitmaps: 位存储 统计用户信息,活跃、不活跃;登录、未登录! Bitmaps位图,数据结构!都是操作二进制位来进行记录,就只有0和1两个状态 命令 使用Bitmaps来记录周一到周二的打卡
setbit sign 0 1
setbit sign 1 0
setbit sign 2 1
setbit sign 3 1
setbit sign 4 1
setbit sign 5 0
setbit sign 6 0
getbit sign 3
bitcount sign
|