为什么需要学习NOSQL (三高)
随着互联网的高速崛起,网站的用户群的增加,访问量的上升,传统(关系型)数据库上都开始出现了性能瓶颈,web程序不再仅仅专注在功能上,同时也在追求性能。所以NOSQL数据库应运而上,具体表现为对如下三高问题的解决:
-
High performance - 对数据库高并发读写的需求
web2.0网站要根据用户个性化信息来实时生成动态页面和提供动态信息,所以基本上无法使用动态页面静态化技术,因此数据库并发负载非常高,往往要达到每秒上万次读写请求。关系数据库应付上万次SQL查询还勉强顶得住,但是应付上万次SQL写数据请求,硬盘IO就已经无法承受了。其实对于普通的BBS网站,往往也存在对高并发写请求的需求,例如网站的实时统计在线用户状态,记录热门帖子的点击次数,投票计数等,因此这是一个相当普遍的需求。(微博 :明星曝光恋情)
-
Huge Storage - 对海量数据的高效率存储和访问的需求
类似Facebook,twitter,Friendfeed这样的SNS网站,每天用户产生海量的用户动态,以Friendfeed为例,一个月就达到了2.5亿条用户动态,对于关系数据库来说,在一张2.5亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。再例如大型web网站的用户登录系统,例如腾讯,盛大,动辄数以亿计的帐号,关系数据库也很难应付。
-
High Scalability && High Availability- 对数据库的高可扩展性和高可用性的需求
在基于web的架构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移,为什么数据库不能通过不断的添加服务器节点来实现扩展呢?
NOSQL的特点
在大数据存取上具备关系型数据库无法比拟的性能优势,例如:
-
易扩展
NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。也无形之间,在架构的层面上带来了可扩展的能力。
-
大数据量,高性能
NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。
-
灵活的数据模型
NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。这点在大数据量的Web2.0时代尤其明显。
-
高可用
NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构。比如Cassandra,HBase模型,通过复制模型也能实现高可用。
-
NoSQL:非关系型数据库 是关系型数据库的一个补充。
-
为什么要使用NOSQL
-
高并发读写需求
-
高效率存储和访问的需求
-
高扩展性和高可用性需求
-
-
主流的NoSQL
-
redis
-
MongoDB
-
什么是Redis
Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,数据是保存在内存里面的. 官方提供测试数据,50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ,且Redis通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
key是string类型,value可以是下面这五种类型
-
字符串类型 string
-
散列类型 hash java-hashmap
-
列表类型 list java-linkedlist
-
集合类型 set java-hashset
-
有序集合类型 sortedset 简称:zset 有序且唯一
Redis支持的数据类型有五种:string、hash、list、set、zset
redis的应用场景
-
缓存(数据查询、短连接、新闻内容、商品内容、首页等等)
-
任务队列。(秒杀、抢购、12306等等)
-
数据过期处理(可以精确到毫秒, 短信验证码)
-
分布式集群架构中 session共享
-
分布式锁实现
-
聊天室的在线好友列表
-
应用排行榜
-
网站访问统计
redis中存储的数据是以key-value的形式存在的.key是string类型,其中==value==支持5种数据类型 .在日常开发中主要使用比较多的有字符串string、哈希hash、字符串列表list、字符串集合set 四种类型,其中最为常用的是==字符串类型==。
字符串(String)
哈希(hash) 类似HashMap 适合存储对象(属性,属性值)
字符串列表(list) 类似LinkedList
字符串集合(set) 类似HashSet
有序的字符串集合(sorted-set或者叫zset) 有序且唯一
Redis字符串(String)
SET key value | 设置指定 key 的值 |
GET key | 获取指定 key 的值 |
DEL key | 删除key |
GETSET key value | 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 |
SETEX key seconds value | 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。 |
SETNX key value | 只有在 key 不存在时设置 key 的值。 |
INCR key | 将 key 中储存的数字值增一。 |
INCRBY key increment | 将 key 所储存的值加上给定的增量值(increment) 。 |
DECR key | 将 key 中储存的数字值减一。 |
DECRBY key decrement | key 所储存的值减去给定的减量值(decrement) 。 |
Redis 哈希(Hash)
命令 | 命令描述 |
---|---|
hset key filed value | 将哈希表 key 中的字段 field 的值设为 value |
hmset key field1 value1 [field2 value2]... | 同时将多个 field-value (字段-值)对设置到哈希表 key 中 |
hget key filed | 获取存储在哈希表中指定字段的值 |
hmget key filed1 filed2 | 获取多个给定字段的值 |
hdel key filed1 [filed2] | 删除一个或多个哈希表字段 |
hlen key | 获取哈希表中字段的数量 |
del key | 删除整个hash(对象) |
HGETALL key | 获取在哈希表中指定 key 的所有字段和值 |
HKEYS key | 获取所有哈希表中的字段 |
HVALS key | 获取哈希表中所有值 |
Redis 列表(List)
命令 | 命令描述 |
---|---|
lpush key value1 value2... | 将一个或多个值插入到列表头部(左边) |
rpush key value1 value2... | 在列表中添加一个或多个值(右边) |
lpop key | 左边弹出一个 相当于移除第一个 |
rpop key | 右边弹出一个 相当于移除最后一个 |
llen key | 返回指定key所对应的list中元素个数 |
LINDEX key index | 通过索引获取列表中的元素 |
LINSERT key BEFORE| AFTER pivot value | 在列表元素前或后插入元素 eg:linsert words before c e pivot表示列表中的元素 value表示新插入的值 |
Redis 集合(Set)
命令 | 命令描述 |
---|---|
sadd key member1 [member2] | 向集合添加一个或多个成员 |
srem key member1 [member2] | 移除一个成员或者多个成员 |
smembers key | 返回集合中的所有成员,查看所有 |
SCARD key | 获取集合的成员数 |
SPOP key | 返回集合中移除的一个随机元素 |
SDIFF key1 [key2] | 返回给定所有集合的差集 |
SUNION key1 [key2] | 返回所有给定集合的并集 |
SINTER key1 [key2] | 返回给定所有集合的交集 |
Redis 有序集合(sorted set | zset)
命令 | 命令描述 |
---|---|
ZADD key score member [score member ...] | 增加元素 |
ZSCORE key member | 获取元素的分数 |
ZREM key member [member ...] | 删除元素 |
ZCARD key | 获得集合中元素的数量 |
ZRANGE key start stop[WITHSCORES] | 获得排名在某个范围的元素列表 查看所有元素:zrange key 0 -1 倒序排列查看:zrevrange key 0 2 |
Redis不仅是使用命令来操作,现在基本上主流的语言都有客户端支持,比如java、C、C#、C++、php、Node.js、Go等。 在官方网站里列一些Java的客户端,有Jedis、Redisson、lettuce、JDBC-Redis、等其中官方推荐使用Jedis和Redisson。 在企业中用的最多的就是Jedis,Jedis同样也是托管在github上.
方法 | 解释 |
---|---|
new Jedis(host, port) | 创建jedis对象,参数host是redis服务器地址,参数port是redis服务端口 |
set(key,value) | 设置字符串类型的数据 |
get(key) | 获得字符串类型的数据 |
hset(key,field,value) | 设置哈希类型的数据 |
hget(key,field) | 获得哈希类型的数据 |
lpush(key,values) | 设置列表类型的数据 |
lpop(key) | 列表左面弹栈 |
rpop(key) | 列表右面弹栈 |
sadd(String key, String... members) | 设置set类型的数据 |
zrange(String key, long start, long end) | 获得在某个范围的元素列表 |
del(key) | 删除key |
exists(key) | 判断key是否存在 |
jedis的介绍
方法 | 解释 |
---|---|
new Jedis(host, port) | 创建jedis对象,参数host是redis服务器地址,参数port是redis服务端口 |
set(key,value) | 设置字符串类型的数据 |
get(key) | 获得字符串类型的数据 |
hset(key,field,value) | 设置哈希类型的数据 |
hget(key,field) | 获得哈希类型的数据 |
lpush(key,values) | 设置列表类型的数据 |
lpop(key) | 列表左面弹栈 |
rpop(key) | 列表右面弹栈 |
sadd(String key, String... members) | 设置set类型的数据 |
zrange(String key, long start, long end) | 获得在某个范围的元素列表 |
del(key) | 删除key |
exists(key) | 判断key是否存在 |