NoSQL
为什么要使用NoSQL
单个数据库架构下,数据存储的瓶颈是什么?
- 数据量过大,一个机器放不下
- 数据索引过大,一个机器的内存放不下
- 读写混合情况下的访问量一个实例无法承受
Web数据库架构的发展
-
优化数据库的结构和索引,使用缓存技术缓解数据库的压力(Memcached+MySQL+垂直拆分)
-
MySQL主从复制和读写分离
-
分库分表+水平拆分+MySQL集群
-
MySQL的扩展性瓶颈:扩展性差、大数据下IO压力大、表结构更改困难
-
如今:负载均衡等一系列架构
为什么使用NoSQL?
传统数据库难以处理网状数据或大量无固定结构的数据
NoSQL的特点
易扩展:数据之间无关系
大数据量高性能:NoSQL的Cache是记录级,MySQL的Cache是QueryCache,粒度不同
灵活的数据类型:随时可以存储自定义的数据格式
RDBMS vs NoSQL
RDBMS(Relational Database Management System):
- ACID
- 高度组织化结构化数据
- 结构化查询语言
- 数据和关系都存储在单独的表中
- 事务
NoSQL:
- Not Only SQL
- 没有声明性查询语言
- 没有预定义的模式
- K-V存储、列存储、文档存储、图形数据库等
- 最终一致性,而非ACID
- 非结构化和不可预知的数据
- CAP定理
- 高性能、高可用性和可伸缩性
K-V、Cache和Persistence
Redis一个高性能的K-V分布式内存数据库
Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启时可以再次加载进行使用
Redis不仅支持简单的K-V(string)型数据,还支持list、set、zset、hash等数据结构的存储
Redis支持数据的备份,即master-slave模式的数据备份
NoSQL经典应用:淘宝网商品的相关数据
- 商品基本信息: MySQL/Oracle
- 商品描述、详情、评价信息(多文字类):文档数据库MongoDB
- 商品图片:分布式文件系统(淘宝的TFS、Google的GFS、Hadoop的HDFS)
- 商品关键字:ISearch
- 商品的波段性的热点高频信息:Tair、Redis、Memcached
- 商品的交易、价格计算、积分累计:支付宝和第三方支付接口
难点:数据类型多样化、数据源多样化和变化重构、数据源和数据服务的耦合
解决方案:统一数据平台服务层(UDSL)
NoSQL数据模型
K-V、BSon(Binary Json)、列族、图形
CAP+BASE
传统ACID:Atomicity、Consistency、Isolation、Durability
CAP(只能3选2):Consistency(强一致性)、Availability(可用性)、Partition tolerance(分区容错性)
BASE:Basically Available(基本可用)、Soft state(软状态)、Eventually consistent(最终一致)
Redis(Remote Dictionary Server)
特点
-
内存存储和持久化
-
取最新n个数据的操作
-
设定过期时间
-
发布、订阅消息系统
-
定时器、计数器
5大数据类型
string:二进制安全,可以存储jpg图片或序列化对象。一个redis字符串value最大可以是512M
hash:一个string类型的field和value的映射表,适合用于存储对象,类似于Map<String,Object>
list:底层是通过链表实现的。可以添加元素至头部或尾部
set:集合,底层基于hashtable
zset:sorted set,每个元素都会关联一个double类型的分数,通过分数来进行排序
常用命令
key:keys *
exsits [key]
move [key] [db]
expire [key] [seconds]
ttl [key]
type [key]
del[key]
string:set
/get
/del
/append
/strlen
incr
/decr
/incrby
/decrby
(仅对数字有效) getrange
/setrange
setex
(set with expire) setnx
(set if not exist) mset
/mget
/msetnx
get
/set
list:lpush
/rpush
/lrange
(l/r代表left/right) lpop
/rpop
lindex
llen
lrem
ltrim
rpoplpush
lset
linsert...before/after
set:sadd
/smembers
/sismember
scard
srem
srandmember
spop
smove
sdiff
sinter
sunion
hash:hset
/hget
/hmset
/hmget
/hgetakk
/hdel
hlen
hexists
hkeys
/hvals
hincrby
/hincrbyfloat
hsetnx
zset:zadd
zrange
/zrevrange
(withscores) zrangebyscore
/zrevrangebyscore
(使用'('表示开区间,使用limit对结果进行截取) zrem
zcard
/zcount
zrank
zscore
zrevrank
Redis的配置文件:redis.conf
GENERAL(通用):
- daemonize(是否后台运行)、pidfile(pid写入的文件路径)
On Windows, daemonize and pidfile are not supported.
- port:6379
- tcp-backlog:511(bachlog是一个队列,等于tcp未完成三次握手队列+已完成三次握手队列)
- bind:(绑定的主机地址)
- timeout:0(超时将关闭client连接,0代表不关闭)
- tcp-keepalive:0(进行keepalive检测的时间,0代表不关闭,建议设置为60)
- loglevel:notice(警报级别,可取debug、verbose、notice、warning)
- databases:16(数据库数量)
SECURITY(安全):Redis认证默认关闭
开启认证:
config set requirepass "[password]"
然后操作前使用下列语句进行权限认证:
auth [password]
LIMITS(限制)
maxclients:10000(最大连接数)
maxmemory:(最大内存,到达最大内存后无法进行写入操作,但可以继续读取)
maxmemory-policy:noeviction(过期策略,可选项如下)
volatile-lru -> remove the key with an expire set using an LRU algorithm
allkeys-lru -> remove any key according to the LRU algorithm
volatile-random -> remove a random key with an expire set
allkeys-random -> remove a random key, any key
volatile-ttl -> remove the key with the nearest expire time (minor TTL)
noeviction -> don't expire at all, just return an error on write operations
maxmemory-sample:5(样本数量,越高可以使LRU或TTL越精确,但会增加CPU功耗)
待续~