Showing posts with label Shopping System. Show all posts
Showing posts with label Shopping System. Show all posts

Saturday, March 12, 2016

How to Design Distributed Priority Queue



http://en.clouddesignpattern.org/index.php/CDP:Priority_Queue_Pattern
There are cases where a large number of batch jobs may need processing, and where the the jobs may need to be re-prioritized.

A queue is used in controlling batch jobs. The queue need only be provided with priority numbers. Job requests are controlled by the queue, and the job requests in the queue are processed by a batch server. In Cloud computing, a highly reliable queue is provided as a service, which you can use to structure a highly reliable batch system with ease. You may prepare multiple queues depending on priority levels, with job requests put into the queues depending on their priority levels, to apply prioritization to batch processes. 

  • You can increase or decrease the number of servers for processing jobs to change automatically the processing speeds of the priority queues and secondary queues.
  • You can handle performance and service requirements through merely increasing or decreasing the number of EC2 instances used in job processing.
  • Even if an EC2 were to fail, the messages (jobs) would remain in the queue service, enabling processing to be continued immediately upon recovery of the EC2 instance, producing a system that is robust to failure.

  • Use SQS to prepare multiple queues for the individual priority levels.
  • Place those processes to be executed immediately (job requests) in the high priority queue.
  • Prepare numbers of batch servers, for processing the job requests of the queues, depending on the priority levels.
  • Queues have a message "Delayed Send" function. You can use this to delay the time for starting a process.
https://www.quora.com/Distributed-Systems/How-to-implement-a-high-availability-priority-Queue-that-can-easily-scale
 create one SQS queue per priority level (assuming a fixed set of priorities). At that point you have a number of options of how to pop off of these queues. The algorithm that I settled on is as follows:

I issue N pop requests against the highest priority queue then M requests against the next highest queue (where M < N) and so on such that each queue gets fewer pop requests as the priority decreases. Since N can be quite large if at any point that particular queue is drained I short circuit the loop and go to the next lowest priority queue.

http://curator.apache.org/curator-recipes/distributed-priority-queue.html
queue.put(aMessage, priority);
https://cwiki.apache.org/confluence/display/CURATOR/TN4
ZooKeeper makes a very bad Queue source.
The ZooKeeper recipes page lists Queues as a possible use-case for ZooKeeper. Curator includes several Queue recipes. In our experience, however, it is a bad idea to use ZooKeeper as a Queue:
  • ZooKeeper has a 1MB transport limitation. In practice this means that ZNodes must be relatively small. Typically, queues can contain many thousands of messages.
  • ZooKeeper can slow down considerably on startup if there are many large ZNodes. This will be common if you are using ZooKeeper for queues. You will need to significantly increase initLimit and syncLimit.
  • If a ZNode gets too big it can be extremely difficult to clean. getChildren() will fail on the node. At Netflix we had to create a special-purpose program that had a huge value for jute.maxbuffer in order to get the nodes and delete them.
  • ZooKeeper can start to perform badly if there are many nodes with thousands of children.
  • The ZooKeeper database is kept entirely in memory. So, you can never have more messages than can fit in memory.

https://www.quora.com/Whats-a-good-distributed-queue

1. 如何设计一个priorityqueue service,client可以submit job request然后server按照priority执行
https://www.quora.com/Distributed-Systems-How-to-implement-a-high-availability-priority-Queue-that-can-easily-scale
Build something with Redis, which supports list operations. If you want to write your own List/Queue as API, go for it. Or if you want to use SQS, use it.
Do the replication yourself if you are unsure about your Queue unavailability.
Shard it yourself based on time, task queue name or priority. Let's go with the priority approach.
Step 2:
Here is where you can work out a variety of logical ways to dequeue:
Assign weights to each queue. At every dequeue step, add weights to each respective queue per unit time, and subtract one for each task you dequeue. To avoid starvation, use a round robin for each time you dequeue, and you shift to the next.
Return a set of tasks to each worker.
Step 3:


High availability priority queue that can scale

The trick I'm currently using is to create one SQS queue per priority level (assuming a fixed set of priorities). At that point you have a number of options of how to pop off of these queues. The algorithm that I settled on is as follows:

I issue N pop requests against the highest priority queue then M requests against the next highest queue (where M < N) and so on such that each queue gets fewer pop requests as the priority decreases. Since N can be quite large if at any point that particular queue is drained I short circuit the loop and go to the next lowest priority queue.


https://github.com/Netflix/curator/wiki/Distributed-Priority-Queue

Saturday, January 9, 2016

订单系统中并发问题和锁机制的探讨



http://massivetechinterview.blogspot.com/2015/12/how-to-design-12306.html
http://www.cnblogs.com/leefreeman/p/3711470.html
    假设在一个订单系统中(以火车票订单系统为例),用户A,用户B都要预定从成都到北京的火车票,A、B在不同的售票窗口均同时查询到了某车厢卧铺中、下铺位有空位。用户A正在犹豫订中铺还是下铺,这时用户B果断订购了下铺。当用户A决定订下铺时,系统提示下铺已经被预订,请重新选择铺位。在这个系统场景中,我们来探讨一下,火车票系统是怎样处理并发事件以及怎么利用锁机制来避免重复订票的。
设想的方案
方案1:
    为了避免重复订票,大部分人会想到在做订票操作前,去数据库查询该铺位是否已经被预订,假设“铺位”数据库表增加标记字段FLAG(空闲:0;已预订:1),如果查询到铺位的FLAG字段值为1,那么预订就不成功,如果为0就成功预订,并把FLAG置为1。这种方案如果在业务量很少的系统中,或许可行。但业务量较大时,特别是火车票这样的业务量,就会出现问题。问题在,当用户A、用户B同时对同一铺位预订时,虽说是“同时”,但对于数据库操作来说一定是有先后顺序的,假设A在查询该铺位的FLAG时,值为0,准备预订并将值设为1,而与此同时B已经预订成功,并已将FLAG设为1。而A因为没有即时查询到FLAG=1,因此也预订成功,又将FLAG设为1。
A      FLAG=0      时刻=T1   (查询)
B      FLAG=0      时刻=T2   (查询)
B      FLAG=1      时刻=T3   (更新)
A      FLAG=1      时刻=T4   (更新)
这样就造成了重复订票,在购票高峰期,使用这样的方案,重复订票不可避免。
方案2:
    我们想到了利用数据库的悲观锁来解决这个问题,设想假如用户A查询到想预订的票,用户B根本都查询不到,只有A一个人能看到,那是不是没有重复订票的可能了,因为压根没人跟他抢。可以这样实现这个方案:
select * from table where …… for update skip locked,该语句是查询用户指定条件的票信息,并加锁(for update),如果有记录已经被锁则自动跳到下一条记录(skip locked),这样谁先查询谁就可以慢慢的考虑要上铺还是下铺。但火车票系统是这样做的吗?显然不是,因为这样用户体验太不好,票实际还很多,但确看不到买不到,这显然不合理。
方案3:
    我们又想到了从程序层面来解决并发问题,最简便的方式是利用synchronized来处理,但我们要知道一个大型系统必然是集群方式部署的,synchronized只能解决单节点环境的并发问题,要解决此问题还是必须依赖全局性的锁机制。
方案4:
    既然又回到了在数据库上加锁,我们又想一下如果我们在查询时,使用乐观锁,但在预订之前使用悲观锁会怎样呢?例如我们查询时:
select * from table where ……
用户A、用户B都查询到了相同的票信息(中铺和下铺),用户A或用户B在预订时做一次悲观锁:
select * from table where …… for update(只对预订的票做悲观锁)
此时后者在预订时,无法获取该记录的锁,自然就无法预订,避免了重复预订的问题。
 还有方案吗…
http://www.cnblogs.com/leefreeman/p/3711470.html
查询并发。
更新使用队列。
可以每条线路一个表,每个表一个队列。
如果对于一些热点的数据,并发特别高,那需要对每个热点数据配一个队列,通过白名单来配置哪些是热点数据。

总之,并发修改意味着资源竞争,资源有竞争那必须线性处理,即一个个按顺序处理,这是没办法改变的东西。那用队列则是实现线性按顺序的最好办法。高性能队列可以考虑用本地内存队列或高性能的分布式队列如kafka,rocketmq等。



电商系统中的商品模型的分析与设计—续



http://www.cnblogs.com/leefreeman/p/4564886.html
从SPU、SKU开始
    首先我们需要澄清上篇中的这两个概念,在上篇文章中“货品”是指一种概念物品,这种物品并不是一个具体的实物,当它具备具体的属性、价格时,才是一种实物,也就是商品。“商品”就是库存中一个具体的实物。例如:iphone6,就是一种货品,但用户购买的并不是货品而是商品,也就是用户最终购买的可能是:金色-16G-移动版 iphone6。换句话来说,货品是一种产品的称谓(如iphone6),商品是用户购买的具体实物,具备特定的属性(如:金色-16G-移动版)。如果觉得这样理解还是比较混,那么忘记这两个概念,下面讲标准化的名称。
    我们刚才说的iphone6,书面称谓叫“SPU” Standard Product Unit (标准化产品单元),它是最接近用户认知的产品单元,比如用户说,我想买个iphone4、iphone6、小米4,这些都是SPU,也就是用户普遍认知范围内的一种产品。然而在电商系统中只有SPU并没有什么卵用,用户购买时肯定要确定,需要什么颜色、多少G的,支持什么网络。所以,例如金色-16G-移动版 iphone6,就需要一个名称去规范它,这个名称叫“SKU” Stock Keeping Unit(库存单元),换句话理解就是库存里面存的东西,库存里存在东西肯定是具体的某种规格的iphone6。基于这个理解,我们先画下图:
image
    SPU,SKU两个表,有各自的编码,这方便库存统计以及后台系统的管理,另外价格字段是在SKU中,这应该好理解,不同规格的iphone6肯定价格不一样,另外SPU与分类和品牌关联,如iphone6属于“手机”分类,“苹果”品牌。当然一个SPU也可能属于多个分类,可以做成多对多的关系。有了这个基础,我们再来看电商商品详情页是怎么设计的:
    我们看到这个页面其实是一个SKU的详情页,因为它指定了价格、颜色、版本、容量等信息,不同的颜色、版本、容量其实是不同的价格,不同的SKU。我们如果要实现这个设计,我们需要加两个概念,就是“属性”和“属性选项”。“属性”正如这里的颜色、版本、容量。而“属性选项”则是金色、银色、移动4G版、16gb、64gb等。可以看出“属性”和“属性选项”是一对多的关系,而“属性选项”和SKU则是多对多关系,一个金色-16G-移动版 iphone6,具备“金色”、“16G”,“移动版”多个选项,而一个“金色”选项除了对应iphone6还可以对于iphone4。我们继续画图:
image
    需要注意的是,属性是对于一个分类的,这样设计的目的主要是为了属性能归类管理,也方便在添加产品时,通过分类对属性进行筛选。例如,“手机”分类有颜色、版本、容量等属性,而“衬衫”分类有“颜色”、“尺寸”。这里有博友可能有疑问,如果属性和分类是一对多的关系,那么属性表将会出现一些冗余,比如“手机”、“衬衫”都有颜色属性,但是在属性表中就会两条颜色的记录甚至更多。这里其实可以设计为多对多的关系。一对多的关系,可以在商品规模小、数据量不太大的电商上适应,这样的好处是,可以让产品发布者更好的管理属性选项和发布产品,因为即便是两个颜色的属性,但他们的属性选项确可以不同,对于“手机”来说,可能只有黑、白、金、银等颜色,但对于“衬衫”分类来说选项就可以有“红橙黄绿青蓝紫”甚至有“花格”。所以可以考虑牺牲冗余来提高商家发布者的体验。接下来我们来看另外一个特性——“规格”:
“规格”代表这一个SKU具体的各项参数,是一个详细的产品规格说明,用户可以通过这些参数与其他同类手机做对比。这些参数中,部分参数将参与列表页的筛选条件中
image
    我们可以注意到两幅图,有些规格并不能对应上。这是因为我们在规格表中可以设置哪些规格显示在详细页中,哪些规格显示在列表筛选条件中。最终的商品模型就是这样:
image
    好了,这个电商商品模型的雏形就有了,但一个成熟的大型电商系统模型要比这个复杂的多,光是一个价格都会有一个单独的模块进行管理,比如市场价、进货价、成本价等,要进行成本核算,要与营销活动结合,双11折扣,或者与其他商品打包购买价格更便宜等。总之,需要根据业务的需要进行一步一步的扩展和设计。以后有机会介绍下电商中订单模型。
http://www.cnblogs.com/leefreeman/p/4564886.html

Saturday, December 19, 2015

Linkedin - Get Second/Third Friends



https://engineering.linkedin.com/real-time-distributed-graph/using-set-cover-algorithm-optimize-query-latency-large-scale-distributed

Overview of Query Routing

LinkedIn's distributed graph system consists of three major subcomponents:
  1. GraphDB: a partitioned and replicated graph database.
  2. Network Cache Service (NCS): a distributed cache that stores a member's network and serves queries requiring second degree knowledge.
  3. API layer: the access point for front-ends.
A key challenge in a distributed graph system is that, when the graph is partitioned across a cluster of machines, multiple remote calls must occur during graph traversal operations. At LinkedIn, more than half the graph queries are for calculating distance between a member and a list of member IDs up to three degrees. In general, anywhere you see a distance icon on the LinkedIn site, there's a graph distance query at the backend.
NCS, the caching layer, calculates and stores a member's second-degree set. With this cache, graph distance queries originating from a member can be converted to set intersections, avoiding further remote calls. For example, if we have member X's second degree calculated, to decide whether member Y is three degree apart from member X, we can simply fetch Y's connections and intersect X's second degree cache with Y's first degree connections.
NCS, the caching layer, calculates and stores a member's second-degree set. With this cache, graph distance queries originating from a member can be converted to set intersections, avoiding further remote calls. For example, if we have member X's second degree calculated, to decide whether member Y is three degree apart from member X, we can simply fetch Y's connections and intersect X's second degree cache with Y's first degree connections.
As someone who was at LinkedIn as we scaled back most search results from including 3rd degree effects to only 1st and 2nd degree effects, I can attest to the computation intensive nature of this.  Currently LinkedIn will show you if a given individual is in your 3rd degree or not (this is easy, because each user's 1st and 2nd degree connections are typically cached somewhere, so this gives you out to the degree of connection between those users if it is 4th or less), but will *never* do something like "grab all of my third degree connections".

I will guess that most likely due to the size of Facebook's graph, it is simply not the case that both the 1st and 2nd degree of most users is kept in memory.  If only your friends are available, if my friends and yours don't overlap, checking whether we're 3rd, or 4th, requires some significant additional computation.


“已知一个函数,输入用户ID,可以返回该用户的所有友好(degree 1 friends),按好友ID从小到大排序。要求实现函数来输出返回一个用户的所有好友的好友(degree 2friends), 以及 degree 3 friends。

这题是想考什么呢?单是3级朋友,是不是BFS就可以解决了?是还要考distributedsystem怎样存取用户信息吗?

论文的关键好像是说,当需要在db搜索(不是cache)的时候,如何很快找到所有的set,这个就是apply set coverage algorithm,尽量争取在一台机器上找到,而不是多台机器。但是它后面有些优化,好像很简单的办法就可以降低latency,这部分没看懂。【 在 kkuser (kkuser!) 的大作中提到: 】
: 学习了下这个链接还看了下相关的paper,似乎有了一些概念。
: 貌似是说建立一个network cache service,里面存有所有member的一层和二层的关系: ,这样的话,求一个member的三层关系,只需要one remote call for each 2nd
: connector。不知道这样理解对不对。
: 另外有个疑问,这个NCS,是个只用其memory的cluster吗?这个cluster可以装的下所: 有用户以及每个用户所有的二层关系吗?
: 一个machine没什么, 像FB那样的, gazillion machine来存你的ID-》 friend
list
: 信息, 你怎没办? machine 之间传来床去?
: bandwidth怎没办? 如果一个user, 像justin bieber那样, 有gazillion个
friends
: , 你怎没办?

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts