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功耗)
待续~