Anzeige
Anzeige

Más contenido relacionado

Anzeige

Último(20)

Anzeige

Nosql三步曲

  1. NoSQL三步曲 朱国能-Gallen.Chu http://www.84zhu.com guoneng.zhu@gmail.com
  2. 目录 海选 • NoSQL选型 • Redis面对面 相亲 结婚 • Redis实践
  3. 海选- NoSQL选型
  4. NoSQL选型 用MongoDB的一句设计哲学开始 • Databases are specializing – the “one size fits all” approach no longer applies.
  5. 我们为什么要使用NOSQL非关系数据库? High • 对数据库高并发读写的需求 performance • 对海量数据的高效率存储和访 Huge Storage 问的需求 High Scalability • 对数据库的高可扩展性和高可 && High Availability 用性的需求
  6. 关系数据库的很多主要特性? 数据库事务一致性需求 数据库的写实时性和读实时性需求 对复杂的SQL查询,特别是多表关联查询的需求
  7. 选型原则 高并发快 速读写 CPU资源 可用性 消耗 文档齐全/ 一致性 社区活跃 原则 客户端 可扩展 /API支持 海量数据 …… 的高效读 写
  8. 选型原则 Consistency CAP Availability Tolerance of network Partition Basically 三大基石 Available BASE Soft state Eventually 最终一致性 consistent 理论依据 五分钟法则
  9. NoSQL比较
  10. 我们需要什么? • 高并发快速读写 • 海量数据高效读写 • 高可用性 • 排行、热门、分类数据结构灵活 • 简单的API、客户端支持 • 文档完善、社区活跃 • 支持良好、版本更新活跃 • 可以容忍最终一致性 • 可以容忍client分区、集群
  11. 相亲-Redis面对面
  12. What is Redis? What is sponsored by: • 全名 REmote DIctionary Server • Redis is an open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. • key value store? cache? memory database? data structure server?
  13. 优点 • FAST both read and write • data can dump to disk • master-slave • many useful data structure • Active community/ Antirez
  14. 缺点 • Physical memory limit • Auto-sharding / Cluster • Scale ability • Automatic failover switch
  15. Fast • 根据 Redis 官方的测试结果:在 50 个并发的情况下请求 10w 次,写 的速度是 110000次/s,读的速度是 81000 次/s • 测试环境: • 1. 50 个并发,请求 100000 次 • 2. 读和写大小为 256bytes 的字符串 • 3. Linux2.6 Xeon X3320 2.5GHz 的服务器上 • 4. 通过本机的 loopback interface 接口上执行 • 地址: • http://code.google.com/p/redis/wiki/Benchmarks • http://redis.io/topics/benchmarks
  16. 性能对比 小数据:500W条数据;每个value:100 bytes
  17. 性能对比 大数据:500W条数据;每个value:20k bytes
  18. Why Fast • Libevent。和Memcached不同,Redis并没有选择libevent。Libevent 为了迎合通用性造成代码庞大(目前Redis代码还不到libevent的1/3)及 牺牲了在特定平台的不少性能。Redis用libevent中两个文件修改实现 了自己的epoll event loop(4)。业界不少开发者也建议Redis使用另外 一个libevent高性能替代libev,但是作者还是坚持Redis应该小巧并去 依赖的思路。一个印象深刻的细节是编译Redis之前并不需要执行 ./configure。 • CAS问题。CAS是Memcached中比较方便的一种防止竞争修改资源 的方法。CAS实现需要为每个cache key设置一个隐藏的cas token, cas相当value版本号,每次set会token需要递增,因此带来CPU和内 存的双重开销,虽然这些开销很小,但是到单机10G+ cache以及 QPS上万之后这些开销就会给双方相对带来一些细微性能差别(5)。
  19. Useful data structure 键(keys) 值(values) page:index.html <html><head>[...] String users_logged_in_today { 1, 2, 3, 4, 5 } Sets latest_post_ids [201, 204, 209,..] List users_and_scores joe ~ 1.3483 ZSets bert ~ 93.4 fred ~ 283.22 chris ~ 23774.17
  20. DUMP • snapshot(RDB) – 定时将内存的快照(snapshot)持久化到硬盘,这种方法缺点是持久 化之后如果出现crash则会丢失一段数据。 • AOP(append only mode) – 写入内存数据的同时将操作命令保存到日志文件,在一个并发更 改上万的系统中,命令日志是一个非常庞大的数据,管理维护成 本非常高,恢复重建时间会非常长,这样导致失去aof高可用性本 意。
  21. RDB • Fork一个进程,利用copy on write原理,遍历所有的db的hash table,进行整库的dump • Save命令,shutdown命令,slave启动都会触发 • 利用LZF进行压缩 • 持久化触发条件: • #sava 900 1 • #save 300 10 • #save 60
  22. BGREWRITEAOF • 避免aof文件过大 • 2.4版本增加自动的bgrewriteaof • auto-aof-rewrite-min-size 64mb • auto-aof-rewrite-percentage 100 • 手动bgrewriteaof
  23. Best redo-logo • 当redisserver异常crash掉的时候,重启时将会进行如下的操作: – 假如只配置了aof,启动时加载aof文件 – 假如同事配置了rdb/aof,启动时只加载aof文件 – 假如只配置rdb,启动时将加载dump文件 • 在非创建快照期间追加redo-log,在完成快照后清除redo-log
  24. 存储模式 • VM方式:将数据分页存放,由应用(如Redis)或者操作系统(如Varnish)将访 问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存 中。应用实现VM缺点是代码逻辑复杂,如果业务上冷热数据边界并不分明, 则换入换出代价太高,系统整体性能低。不少抢鲜的网友在微博上也反馈过 使用VM种种不稳定情况。 (目前Redis使用的方式) • 磁盘方式:所有的数据读写访问都是基于磁盘,由操作系统来只能的缓存访 问的数据。由于现代操作系统都非常聪明,会将频繁访问的数据加入到内存 中,因此应用并不需要过多特殊逻辑。MongoDB就是这种设计方式。这种方 式也有一些已知的缺点,比如操作MMap写入磁盘由操作系统控制,操作系 统先写哪里后写哪里应用并不知情,如果写入过程中发生了crash则数据一致 性会存在问题。 (作者称其为MongoDB的方式) • Diskstore:实际原理和mysql+memcache方式类似,只不过将两者功 能合二为一到一个底层服务中,简化了调用。(作者打算使用的新方 式,alpha版本,Demo)
  25. Replication • master可以有多个slave • 除了多个slave连到相同的master外,slave也可以连接其他slave形成 图状结构 • 主从复制不会阻塞master。也就是说当一个或多个slave与master进 行初次同步数据时,master可以继续处理client发来的请求。相反 slave在初次同步数据时则会阻塞不能处理client的请求。 • 主从复制可以用来提高系统的可伸缩性,我们可以用多个slave 专门用 于client的读请求,比如sort操作可以使用slave来处理。也可以用来 做简单的数据冗余 • 可以在master禁用数据持久化,只需要注释掉master 配置文件中的 所有save配置,然后只在slave上配置数据持久化 • slaveof 172.16.3.35 6379 #指定master的ip和端口 • slave重连无增量复制,slave表重建
  26. Author
  27. 应用场景 • 取最新N个数据的操作 • 排行榜应用,取TOP N操作 • 需要精准设定过期时间的应用 • 计数器应用 • Uniq操作,获取某段时间所有数据排重值 • 实时系统,反垃圾系统 • Pub/Sub构建实时消息系统 • 构建队列系统 • 缓存
  28. 2.4版本改进 • 对Sorted Sets的内存优化 • RDB文件持久化提速 • 提供批量写入功能 • 改用jemalloc的内存分配模式 • 减少 copy-on-write 使用 • INFO输出内容增强 • VM机制彻底废弃 • 总的来说2.4版本会在各方面有性能上的提升
  29. Why 6379 Why? 6379 6379在是手机按键上MERZ对应的号码 MERZ取自意大利歌女Alessia Merz的名字
  30. 结婚- Redis实践
  31. Redis容量规划及建议 • 数据项: value保存的内容是什么,如用户资料 • 业务数据类型: 如String, List, set • 数据大小: 如100字节 • 记录数: 如100万条(决定是否需要拆分) • 数据增多如何扩展? • 读写瓶颈如何扩展? • 不仅要规划还要严密监控! • sharding策略与HA(rolling/pre-sharding/双写/多slave) • 使用Pipeline减小网络IO/原子操作 • Redis的最佳使用方式是 in-memory
  32. Redis数据库的键值设计(一) mysql> select * from login; +---------+----------------------------+-------------------------+--------------------------------------+ | user_id | name | login_times | last_login_time | +---------+----------------------------+-------------------------+--------------------------------------+ | 1 | Doug.Wang | 5| 2011-10-01 00:00:00 | | 2 | Jeff.Tu | 1| 2011-10-01 00:00:00 | | 3 | Gallen.Chu | 2| 2011-11-01 00:00:00 | +----------+---------------------------+-------------------------+-------------------------------------+ key表名:主键值:列名 Set login:1:login_times 5 Set login:2:login_times 1 Set login:3:login_times 2 Set login:1:last_login_time 2011-10-1 Set login:2:last_login_time 2011-10-1 Set login:3:last_login_time 2011-11-1 Set login:1:name “Doug.Wang” Set login:2:name “Jeff.Tu”” Set login:3:name “Gallen.Chu”
  33. Redis数据库的键值设计(二) 排序需求 zadd post:post_times 15 1 zadd post:post_times 11 2 zadd post:post_times 28 3 #对该应用的评论次数自增1 ret = r.zincrby(“post:post_times", 1, app_id) 获得评论次数最多的应用,逆序排列取的排名第N的应用 ret = r.zrevrange(“post:post_times", 0, N-1)
  34. Redis数据库的键值设计(三) Set app:1:name "冒泡音乐盒" Set app:2:name "股票指南" Set app:3:name "幻想三国" sadd appTag:application 1 sadd appTag:application 2 sadd appTag:tools 2 sadd appTag:webgame 3 即属于application又属于tools的应用? inter_list = redis.sinter("appTag:application", "appTag:tools") 即属于application,但不属于tools的应用 inter_list = redis.sdiff("appTag:application", "appTag:tools") 属于application和属于tools的书的合集? inter_list = redis.sunion("appTag:application", "appTag:tools")
  35. Example • A_start 10, A_end 20 • B_start 30, B_end 40 • redis 127.0.0.1:6379> zadd ranges 10 A_start (integer) 1 • redis 127.0.0.1:6379> zadd ranges 20 A_end (integer) 1 • redis 127.0.0.1:6379> zadd ranges 30 B_start (integer) 1 • redis 127.0.0.1:6379> zadd ranges 40 B_end (integer) 1 • redis 127.0.0.1:6379> zrangebyscore ranges (15 +inf LIMIT 0 1 1) "A_end“ • redis 127.0.0.1:6379> zrangebyscore ranges (25 +inf LIMIT 0 1 1) "B_start"
  36. 使用hset代替set 对象:skyapp id : 1 name : 天气助手 appid : 2914 created_time : 132013777338 HSET skyapp:1 name “天气助手” HSET skyapp:1 appid 2914 HSET skyapp:1 created_time 132013777338 • 结构化数据存取 --------------------------------------------------- • 提高内存使用率 HLEN skyapp:1 == 3 HGET skyapp:1 name == “天气助手” HKEYS skyapp:1 == name , appid, created_time HGETALL skyapp:1 == name => 天气助手 time => 2914 created_time => 132013777338
  37. 使用Pipleline模式 •发送多个命令,一次性接收多个命令,减少网络IO次数 •服务器将命令结果放进queue,再返回给客户端 Client: INCR X Client: INCR X Server: 1 Client: INCR X Client: INCR X Client: INCR X Server: 2 Client: INCR X Client: INCR X Server: 1 Server: 3 Server: 2 Client: INCR X Server: 3 Server: 4 Server: 4
  38. 不要使用VM • Redis VM 不靠谱,作者在2.4版本中已经彻底放弃了VM – 症状: • 代码逻辑复杂 • 系统整体性能低 • 如业务冷热数据边界不分明,换入换出代价太高 • 数据DUMP的时候内存耗光,CPU100% – 方案: • 加大物理内存 • 数据sharding
  39. 集群架构(一)  主从架构 • Redis缺少同步机制常见的check point和校验机制 • 如果同步转发丢失,一致性无法保证,只有slave重启时全量加载才 能修复 – 方案:主库在内存中运行,从库不提供线上服务只做持久化备份 Master Replication Slave 纯内存 备份、持久化
  40. 集群架构(二)  单机多节点 ( 节点数=CPU - 1 )  分布式缓存 (一致性哈希) Redis1:6380 每天2点 6G redis redis Redis2:6381 每天3点 6G Redis3:6382 每天4点 6G 预留6G redis redis  分时间段 bgrewriteaof  充分提高内存使用率
  41. 集群架构(三)  Sharding 数据分片 应用层 sharding R/ R/ R/ W W W master1 master2 master3 slave1 slave2 slave3 备份 备份 备份
  42. 集群架构(四) •All nodes are directly connected with a service channel. •TCP baseport+4000, example 6379 -> 10379. •Node to Node protocol is binary,optimized for bandwidth and speed. •Clients talk to nodes as usually, using ascii protocol, with minor additions. •Nodes don't proxy queries.
  43. Redis客户端 • 各种语言客户端支持。 • Jedis,ShardJedis,ShardJedisPipeline • 支持客户端分布式,ShardJedis。一致性哈希算 法,采用TreepMap<String,ShardInfo>存储redis 节点,murmur哈希函数计算key和server的值。 默认虚拟160个节点,支持权重配置。 • 连接池管理。JedisPool。
  44. WEB界面管理工具 • 一个PHP的Redis WEB管理工具phpRedisAdmin • 项目地址:https://github.com/ErikDubbelboer/phpRedisAdmin • 演示demo:http://dubbelboer.com/phpRedisAdmin/
  45. 附:参数说明(一) 配置项 说明 daemonize no 是否以后台进程运行,默认为no pidfile 如以后台进程运行,则需指定一个pid,默认/var/run/redis.pid port 6379 监听端口,默认为6379 bind 127.0.0.1 绑定主机IP,默认值为127.0.0.1 timeout 300 超时时间,默认为300(秒) loglevel 日志记录等级,有4个可选值,debug,verbose(默认值),notice,warning logfile 日志记录方式,默认值为stdout slaveof 当本机为从服务时,设置主服务的IP及端口。在启动时,REDIS会自动从 MASTER上把数据先同步过来,而无需我们手动进行。MASTER上每有一次 落地保存,会自动向SLAVE进行同步。 masterauth 当本机为从服务时,设置主服务的连接密码 requirepass 连接密码 maxclients 最大客户端连接数,默认不限制 maxmemory 设置最大内存,达到最大内存设置后,Redis会先尝试清除已到期或即将到期 的Key,当此方法处理后,任到达最大内存设置,将无法再进行写入操作。
  46. 附:参数说明(二) 配置项 说明 save 900 1 900秒内有1个改变, save 300 10 300秒内有10个改变, save 60 10000 60秒内有10000个改变, redis就会内存中的key保存到数据库文件中去 rdbcompression 存储至本地数据库时是否压缩数据,默认为yes dbfilename 本地数据库文件名,默认值为dump.rdb dir 本地数据库存放路径,默认值为 ./ Appendonly 是否在每次更新操作后进行日志记录,开启AOF appendfilename 更新日志文件名,默认值为appendonly.aof appendfsync 新日志条件,共有3个可选值。no表示等操作系统进行数据缓存同步到磁盘, always表示每次更新操作后手动调用fsync()将数据写到磁盘,everysec表示 每秒同步一次(默认) hash-max- 当hash中包含超过指定元素个数并且最大的元素没有超过临界时,hash将以 zipmap-entries 一种特殊的编码方式(大大减少内存使用)来存储 hash-max- hash中一个元素的最大值 zipmap-value
  47. 附:参数说明(三) 配置项 说明 vm-enabled 是否使用虚拟内存,默认值为no vm-swap-file 虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享 vm-max-memory 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory 设置多小,所有索引数据都是内存存储的 (Redis的索引数据就是keys),也就 是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。 默认值为0 vm-page-size 虚拟内存文件以块存储,默认每块32bytes vm-pages 虚拟内在文件的最大数,默认134217728 vm-max-threads 可以设置访问swap文件的线程数,设置最好不要超过机器的核数,如果设置 为0,那么所有对swap文件的操作都是串行的.可能会造成比较长时间的延 迟,但是对数据完整性有很好的保证.
  48. 附:Redis扩展阅读 我怎么获得更多,更全的Redis信息? 1、http://code.google.com/p/redis/ 2、http://redis.io 3、http://antirez.com/ 4、http://blog.nosqlfan.com/tags/Redis 5、http://redis.readthedocs.org/en/2.4/index.html 6、http://www.google.com
  49. Q&A
Anzeige