
redis
#Redis
发展史
1.单机MySQL 原始模型
出现的问题:
1.数据量大
2.数据的索引(B+Tree),一个机器放不下
3.访问量(读写混合),一个服务器受不了
解决:
2.使用Memcached+Mysql+垂直拆分(读写分离),多加数据库
3.分库分表+水平拆分+MySQL集群
MySQL的引擎:
MyISAM: 表锁
Innodb: 行锁
现在的结构
NoSql
1.什么是NoSql
非关系型数据库:存储一些不需要固定格式的数据 不需要过多的操作就可以横向扩展
关系型数据库:比如行和列
2.为什么要用
用户的个人信息,社交网络,地理位置,用户自己产生的数据,用户的日志爆发增长,
这个时候就需要使用Nosql,
3.NoSql的特点
解耦
1.方便扩展(数据之间没有关系)
2.大数据量高性能(Redis一秒可以写8万次,读11万次,NoSql的缓存记录级是一种细粒度的缓存,性能会更高)
3.数据类型多样性(不需要事先设计数据库,随取随用)
4.传统的数据库和NoSql
传统的:
结构化组织
SQL
数据和关系都存储在单独的表中
DDL DQL
严格的一致性
基础的事务
NoSql:
不仅仅是数据
没有固定的查询语言
键值对存储,列存储,文档存储,图形数据库
最终一致性
CAP和BASE(异地多活)
高性能,高可用,高可扩
5.3V加3高
3V:
1.海量的(Volume)数据
2.多样的Variety
3.实时的Velocity
3高:
1.高并发
2.高可扩(水平拆分,)
3.高性能
nosql数据模型
nosql四大分类
1键值对存储,2列存储,3文档存储,4图形数据库
1.KV键值对:
Map<String,Object>2.文档型:
bson格式,和JSON一样
MongoDB是一个基于分布式文件存储的数据库,主要用来处理大量文档
并且是一个介于关系型数据库和非关系性数据库之间的产品
而且是非关系型数据库中功能最丰富,最像关系型数据库的3.列存储:
Hbase
分布式文件系统4.图形数据库:
社交关系图
CAP
BASE
Redis入门
1.是什么?
是一个开源的使用ANSI C语言编写的,支持网络,可基于内存亦可持久化的日志型,Key-Value数据库,并提供多种语言的API。
2.能做什么?
1.内存储存,持久化
2.效率高,可以用于告诉缓存
3.发布订阅系统
4.地图信息分析
5.计时器,计数器(浏览量)
3.特性
1.持久化
2.集群
3.事务
4.Redis安装
Windows:
GitHub下载
1.开启服务
Linux:
redis的基本知识
redis数据库
redis默认有16个数据库,默认使用的是第一个,可以使用Select切换
select 3 #切换数据库
DBSIZE #查看大小
Keys* #查看所有的key
flusall #清空全部
flusdb #清空当前库
Redis是单线程的
基于内存操作,瓶颈是基于机器的内存和网络带宽
为什么单线程快
多线程(CPU会上下文切换)CPU>内存>硬盘
核心是redis是将所有的数据放在内存中,所以使用单线程,对于内存来说没有上下文切换,多次读写都是在一个CPU上的
RedisKey
EXISTS key #是否有此key
move key 1 #移动key 到某个库
del key #移除key
EXpire key s #设置key过期时间
ttl key #查看剩余时间
type key #查看什么类型
APPEND key "xxx" #追加字符串
五大基本数据类型
String
set name "goudan" #存一个key为name的值为goudan
get name #取值 name为key
key * #获得所有的key
EXISTS name #判断一个key是否存在
APPEND key "xxx" #追加字符串 没有此key的话就相当于set key
## i++ 适用于浏览量+1
set views 0 #创建初始化为0
get views #查看
incr views #自增1
decr views #减1
INCRBY views 10 #设置步长
DECRBY views 5 #步长-5
## 取出某些个字符
GETRANGE key 0 3 #获取开头到3的字符 -1是全部 0 1 2 3
##添加字符串
set key1 aaaaa
setrange key1 1 bb #插入bb到下标1 abbaaaa
##setex(set with expire) 设置过期时间
##setnx(set if not exist) 不存在则设置 分布式锁中常用
setex key2 30 "alal" #设置key2的值为alal,30秒过期
setex mykey "lph" #如果mykey不存在,就创建mykey
setex myley "lpggg" #如果存在 则创建失败
##同时设置多个值
mset
mget
mset k1 v1 k2 v2 k3 v3 #一次设置多个值
key * #获得所有的key
"k1"
"k2"
"k3"
mget k1 k2 k3 #取出所有的值
"v1"
"v2"
"v3"
msetnx k1 v1 k4 v4 #原子型操作 要么都成功 : ?
#对象
set user:1{name:zhangsan,age:12}
mset user:1:name lisi #创建一个user对象 name age address
user:1:age 20
user:1:adderss beijing
mget user:1:name user:1:age user:1:address #取出user:1:name的值等。。
##getset 先获取在设置值
getset age 90 #如果不存在值 返回null
null
get age
90
getset age 20 #如果存在值 先返回
90
get age #在显示新存的
20
List
在redis里 list可以做栈,队列,阻塞队列 ,值可重复
#list命令都是L开头
Lpush list one #push 存值
Lpush list two
Lpush list three
LRANGE 0 -1 #取出所有
"three" "tow" "one" #先进先出
Rpush list zoom
LRANGE 0 -1
three tow one zoom #插入到最右边
#移除
LPOP #移除左边的 也就是最后存进去的
RPOP #移除右边的 也就是第一个存进去的
LPOP list #移除列表的第一个元素
tow one
RPOP list #移除列表的最后一个元素
tow
#下标
Lindex
lindex list 1
#移除指定的值
lrem
lrem list 1 one #代表移除1个元素 one
lrem list 2 three #代表移除2个元素 three
#Trim
Ltrim #截取需要的
Lpush mylist "a"
Lpush mylist "b"
Lpush mylist "c"
Lpush mylist "d"
d c b a
ltrim 1 2
c b
#RPOPLPUSH 截取现有list的最后一个元素到一个新的list
Lpush mylist "a"
Lpush mylist "b"
Lpush mylist "c"
Lpush mylist "d"
rpoplpush mylist newmylist
#此时的mylist
#a b c
#此时的newmylist
#d
#lset 更改指定下表的值
lset list 0 ggogog #将list下标为0 的值 改为 ggogog 下标不存在值就会报错
#LINSERT 插入值到某个元素的后面或前面
linsert mylist before "那个元素" "要插入的值" #在某个元素前插入什么值
linsert mylist after "a" "b" #在a元素后插入b
##list总结:
实际就是一个链表 before node after left rigth 都可以插入值
如果key不存在,创建新的链表
如果key存在,新增内容
如果移除key 那么就成了一个空链表
两边插入 和 修改值效率最好
消息队列:左边进去右边出 (lpush rpop)
栈:左边进去左边出 (lpush lpop)