Dynamic Pricing for Resource Consumption in Cloud Service

,


Introduction
In recent years, the development of cloud computing is extremely rapid [1].With the cloud computing, we can deploy different kinds of computing resources in the cloud, rather than a specified server [2].In other words, there is no need to use hardware equipment, which is very convenient for the companies or organizations so they can focus on their core businesses rather than expending resources on computer infrastructure and maintenance [3][4][5][6][7].Therefore, more and more users are looking for the cloud computing, which makes the cloud resource providers emerge.Due to the reason that the service deployed in the cloud may migrate between different resources, and in the meantime mobile users such as smart devices cause the dynamic change in resource consumption, hence, a dynamic pricing scheme is needed for both service providers and consumers.
The traditional cloud resource pricing models can generally be divided into two categories.The first one is on-demand service; i.e., the users should pay for the fee, which is based on the using time and the actual resource consumption.This pricing model is suitable for the short-term users.The second one is reserved service; i.e., each user pays a fixed fee for a month or year and could use the cloud resource during this period of time without limitation.
However, both of the two pricing models have disadvantages.For the first one, users are required to pay a huge fee if they use the cloud resource for a long time.But in this case, the concurrency for these users maybe little; e.g., only one computer is online, and compared with users who have multiple computers online simultaneously, it is unfair to charge users with little concurrency.As for the second one, it is unfair for the users who use the cloud service for little time monthly.They must pay for the same fee with the users who use the cloud resource for a long time.Therefore, it is meaningful to design a more reasonable pricing model for the cloud resources service.
In this paper, for cloud resource, we propose a flexible dynamic pricing model which takes into account occupying time, resource consumption, and maximal concurrency.In

Related Work
Our problem can be divided into two major subproblems: (1) how to design a reasonable pricing model and (2) how to find the maximal concurrency of resource consumption.Therefore, we investigate related work from these two parts, respectively.
For the first part, cloud computing is different from the classic distributed system.The pricing model of the cloud service should take the pricing fairness, evolving system dynamics, and cost of failures into account [9].The existing pricing schemes in the cloud market can be summarized into three types: trading on-demand service, reserved service, and spot service, respectively [10].Trading on-demand service means that the cost of a user is based on the time he used for cloud resources.But users pay a fixed fare for cloud resources in the reserved service.These two static pricing schemes are the main pricing models in the current cloud market [11,12].Different from them, the spot service is a dynamic pricing scheme where users' payments depend on the relation of their demand and the available cloud resource.Based on the main idea of the spot model, many kinds of dynamic pricing model have been proposed in recent literature, like auction mechanisms [13][14][15][16].Zheng et al. [17] developed a predatorprey model which can simulate the interactions between demand and resource and compute the fare of cloud service.Zhang et al. [18] proposed a joint pricing and scheduling strategy and proved the worst-case competitive ratios of the pricing functions.However, none of above works consider the dynamic pricing for cloud service that we do since the algorithm proposed in this paper can efficiently report the total cost for the providers no matter how the service migrates or user behaves.
For the second part, as far as we know, there are few algorithms that can find the maximal concurrency of resource consumption to solve our problem directly.But we find a closed problem called temporal aggregations, in which there are some temporal aggregations operators such as count, sum, and average.These operators are similar to the method of calculating the maximal concurrency.There are also many algorithms to solve temporal aggregations problem.Kline and Snodgrass [19] proposed aggregation tree, which is a data structure, to support incremental computation for temporal aggregation.However, the aggregation tree is unbalanced whose time complexity is ( 2 ) for constructing a tree, where  is the number of intervals.Moon et al. [20] presented a balanced tree algorithm whose time complexity is ( log ), where  is the number of intervals.Besides, Moon et al. [21] also proposed a bucket algorithm and parallelized it on a shared-nothing architecture.Yang and Widom [22] presented a data structure called SB-Tree which combines B-tree [23,24] and segment tree [25].SB-Tree can feedback a query in ( log ) and an update in ( log ), where  is the number of intervals.However, there is a difference between our problem and temporal aggregation.The time interval is a condition given in the temporal aggregation.But in our problem, we do not know when the concurrency of resource consumption is maximal.In other words, we do not have a certain time interval in our problem which needs to be calculated by our algorithm.Therefore, the algorithms for temporal aggregation cannot solve our problem directly.

Pricing Model
As mentioned in Section 1, the maximal concurrency of resource consumption plays an important role in pricing the cloud service.In other words, the price is mainly decided based on the maximal concurrency on cloud servers at the same time.
To further illustrate the meaning of the maximal concurrency, we give an example as follows.Table 1 and Figure 1 show the using time and usage records of four users, A, B, C, and D. Each user record consists of a time interval and its concurrency.The time interval represents the time range of users using the cloud resources.We can easily see that user A uses the cloud resources in time interval [5,10] and his concurrency is 2.
According to Table 1 and Figure 1, we can split the original interval again, which is shown in Table 2.In Table 2, obviously we can see that 11 is all the users' maximal concurrency of resource consumption.So we find out the cost of the cloud resource provider.After that, we can calculate the user's price based on his usage data and the profit for the cloud resource provider.
Next, based on the maximal concurrency of resource consumption, we can design the following price model.

Pricing Model
Modeling the Concurrency.Suppose that there is a rate , which means the cost of each concurrency for the cloud service provider.In addition, in a certain month, the total number of users is  and the maximum concurrency of resource consumption is .Therefore, the cost of the cloud service provider is  =  × .As for users, we propose a new pricing model.Firstly, each user needs to pay for  as the monthly rental.In addition, the provider will charge a fee for each user based on his maximal concurrency.Therefore, a user   should pay price(  ) = max  ×  +  for his resource consumption.Finally, the profit of the cloud service provider is Example.As shown in Figure 2, assume that the user's monthly fare  = 1, the rate  = 2. From time 1 to 7 is a month.The maximum concurrency of each user  1 ,  2 , and  3 is 4, 7, and 5, respectively.The cloud service fare of users  1 ,  2 , and  3 is price( 1 ) = 4 × 2 + 1 = 9, price( 2 ) = 7 × 2 + 1 = 15, and price( 3 ) = 5 × 2 + 1 = 11.The maximum concurrency of resource consumption is the dotted line part in the figure, which is  = 4 + 7 + 5 = 16.Therefore, the profit of the cloud service provider is profit = 9 + 15 + 11 − 16 × 2 = 3.
However, this pricing model has some drawbacks.For example, the user  3 uses the cloud server for a little time.But he needs to pay for more fare than user  1 because of his higher concurrency.Therefore, the merely using concurrency model is not reasonable in some special cases, and we further improve this model by taking resource consumption into account.
Combining Resource Consumption.Assume that a user   has  records of cloud resource consumption on the current month and each record starts at   and ends at    .The concurrency of the record is    .Therefore, the cloud consumption of   is   = ∑  =1 (   −   )   .In addition, the maximal concurrency of user   is max  .The final cloud service fare of   can be calculated by following equation: where 0 <  < 1 is a factor that adjusts the using time and the maximum concurrency of users. is the resource consumption rate which means the cost of each resource consumption. is the maximum concurrency rate. is the monthly rental of cloud service.The values of , , , and  can be adjusted according to actual needs.Example.Still using Figure 2 as an example, assume that the user's monthly rental  = 1, the maximum concurrency rate  = 2, the usage rate  = 1, and  is 0.5.Then the consumption of users  1 ,  2 , and The maximum concurrency of each user  1 ,  2 , and  3 is 4, 7, and 5, respectively.Therefore, the cloud service pare of users  1 ,  2 , and  3 is price( 1 ) = 0.5 × 15 × 1 + 0.5 × 4 × 2 + 1 = 12.5, price(2) = 0.5 × 21 × 1 + 0.5 × 7 × 2 + 1 = 18.5, and price(3) = 0.5×7×1+0.5×5×2+1= 9.5.The profit of cloud service providers is profit = 12.5 + 18.5 + 9.5 − 2 × 16 = 8.5.
This pricing model compensates for the defect of the former price model which only takes the maximum concurrency of resource consumption into account.This pricing model adds the factor of users' resource consumption, which makes the model more reasonable.Besides, we can adjust the coefficient  to adapt to different cloud resources and make the model more flexible.

Algorithm Description
In Section 3, we propose a flexible dynamic pricing model for cloud resources.As the maximal concurrency of resource consumption plays an important role in the pricing model, how to efficiently calculate the maximal concurrency of resource consumption is a difficulty in our problem.Because when we calculate the price for resource consumption in cloud service, we should calculate the maximal concurrency of resource consumption first.Therefore, we propose a new data structure and the operational algorithms based on it to solve this problem.
In this part, we will introduce the new data structure called B++-tree which extends from B+ tree.We first introduce the structure of the B+ tree and then introduce the structure of the B++-tree.Finally, we introduce the insertion, deletion, and split operations of B++-tree, which can calculate the maximal concurrency of resource consumption.
The nodes of B+ tree can store a lot of index entries, which helps reduce the height of the tree.Besides, the leaf nodes of B+ tree are connected by pointers.It is very suitable for the query.The following is a brief introduction for the B+ tree.
Each B+ tree has a parameter called capacity , which determines the maximal capacity for each node.For each interior node, it contains  ( < ) elements and points to  + 1 child nodes.For each leaf node, it contains  ( < ) elements and have a pointer to its right sibling node as shown in Figure 3.In this way, it is efficient to traverse all leaf nodes by utilizing their pointers rather than traversing from the root.
But a simple B+ tree cannot solve our problem, because we need to store the concurrency of resource consumption ... into the tree.So we propose a new data structure called B++tree, which extends from B+ tree.
4.1.Structure of B++-Tree.Different from B+ tree, we add an addition attribute for each leaf node of B++-tree, which is used to store the concurrency of each interval.Note that the interior nodes keep the same structure as the B+ tree and do not have the additional attribute.In this way, the concurrency of all intervals is stored in leaf nodes, and we can only traverse leaf nodes to obtain the final result, which improve the performance of our algorithm efficiently.
In the B++-tree, each node can hold up to  timestamps.If the number of timestamps stored in the node exceeds , we should call split (Section 4.4) process to split the overflowed node into two new nodes.Actually, two adjacent timestamps in a node represent an interval.The interval is a criterion which can help us determine the child node that we need to traverse when we need to insert or delete a new record.The detailed structures of interior nodes and leaf nodes are as follows.
⋅   = [ ⋅  −1 ,  ⋅   ] is the th interval.There are two special conditions: (1) The start time of  ⋅  1 is −∞, if node  is the root node or it is the first child.Otherwise, the start time of  ⋅  1 is   ⋅ −1 , where   is the parent node of  and   ⋅  points to .
(2) The end time of  ⋅   is +∞, if this node is the root node or it is the last child.Otherwise, the end time of  ⋅   is   ⋅   , where   is the parent node of  and   ⋅   points to .Leaf Node. Figure 5 shows the structure of a leaf node.Compared with interior nodes, leaf nodes have additional attributes which store the concurrencies of intervals.The definition of leaf nodes' intervals is the same as interior nodes.Moreover, each leaf node has a pointer which points to its next Input: Interval .Output: B++-tree after inserting .
( Set the common interval of  ⋅  and  as the new interval, add V of  ⋅  and V of  to the new interval ( 6) else (7) search into the child node   of , insert  to   , back to step (2).(8) end if (9) end if (10) end for Algorithm 1: Insert operation.sibling leaf node.Specially, the last leaf node has no pointer.In addition, there is a header pointer pointing to the first leaf node.
For example, Figure 6 plots the example of B++-tree.The first interval of  0 is [−∞, 5] and the last interval of  0 is [15, +∞], because it is a root node.The first interval of  1 is [−∞, 2], because it is the first child of its parent, and the concurrency of the interval is 0. The first interval of  2 is [5,7], and the concurrency of the interval is 2.

Insertion
Main Idea.In this section, we introduce the insert operation.We define the procedure insert (⟨, V⟩, ) as an insert operation, where  indicates the user's usage interval, such as [5,10], V indicates the user's concurrency, and  indicates the node that to insert.Insertion will be firstly processed from the root node  root .We firstly traverse the root node and find the intervals which intersect with .If  root ⋅   intersects with , we search in the  root ⋅   and traverse it in the same way until the leaf nodes.When we traverse to a leaf node   , we find the intervals which intersect with  and add the V to its corresponding concurrency.
Description.Algorithm 1 shows the pseudo code of insertion.The input is the interval , and the output is the B++-tree after insert .Suppose that now we want to insert the record ⟨, V⟩ into the tree.Start from the root node  (line (1)), for each interval  ⋅   of : (1) If  ⋅   intersects with the time interval  and  is a leaf node, and if interval  contains  ⋅   , then add V to ⋅  directly (line (5)).If interval  does not contain ⋅  but only intersects with it, then we take their intersecting interval as a new interval and add V to the new interval.The original interval keeps unchanged (line (2)∼( 5)).
Input: Node  which is overflowed; Output: Node  1 and  2 which are split from . (

Deletion.
The deletion operation is similar to the insertion operation.We can regard the deletion operation as an opposing operation to the insertion.Specifically, if we want to delete the record ⟨, V⟩, we can insert a record ⟨, −V⟩.Therefore, deletion operation can be easily understood without extra explanation.

Split
Main Idea.As records are inserted, the number of leaf nodes' intervals gradually increases.As mentioned above, each node can hold up to  intervals.Therefore, when a node  becomes overflowed, i.e., its number of intervals exceeds , we should split  into two nodes  1 and  2 .The first half intervals of  are assigned to  1 and the remaining intervals of  are assigned to  2 .Suppose   is the parent node of .Because of the split of , the numbers of interval in   will be added 1.If   also become overflowed, split   .Description.Algorithm 2 shows the pseudo code of split.The input is the node  which is overflowed and the output is nodes  1 and  2 which are split from .Suppose that node  is overflowed and currently stores  intervals.We define the procedure as split ().Specific operations are as follows: (1) Node  splits into  1 and  2 .Node  1 retains the first half intervals of the original node ; i.e.,  1 retains the first ⌈/2 − 1⌉ time points.If  is an interior node,  1 also retains the pointer from ⋅ 1 to ⋅ ⌈/2⌉ .If  is a leaf node,  1 also retains the first ⌈/2⌉ values from  ⋅ V 1 to  ⋅ V ⌈/2⌉ .Node  2 retains the rest of intervals, which means  2 retains the time points from  ⋅  ⌈/2⌉+1 to  ⋅  −1 .If  is the interior node,  2 also retains the pointer from ⋅ ⌈/2⌉+1 to ⋅  .If  is the leaf node,  2 also retains the value from  ⋅ V ⌈/2⌉+1 to  ⋅ V  (lines (1)∼( 6)).
Example.For example, Figures 9-10 show us how the nodes split.Suppose that the capacity of the tree is 4.This means if the number of node's intervals exceeds 4, the node needs to be split.The node  3 in Figure 9  the node  3 is leaf node, so  4 keeps the first 3 values and  5 keeps last 2 values.Move  3 ⋅  ⌈/2⌉ to  0 .The result of the split is shown in Figure 10.

Query for the Maximal Concurrency.
When the index building is complete, we can traverse all leaf nodes to acquire each interval and corresponding concurrency.Since all leaf nodes are connected by pointers, we can easily traverse these leaf nodes sequentially without traversing any interior node.
When we get the maximal concurrency, we get the cost of cloud resource provider.Then we can use our pricing model to charge each user.

Experiment
In this section, we provide experimental evaluation of our algorithm.We simulate five datasets which contain 10,000, 100,000, 500,000, 1 million, and 2 million records, respectively.Each record in the dataset contains the user's name, time interval, and the concurrency.For example, "1--> [2017-07-31 11:46:15, 2017-07-31 21:02:56], 4" is a record."1" is the user's name, and his time interval is from "2017-07-31 11:46:15" to "2017-07-31 21:02:56"; the concurrency is 4. We design a series of experiments in the construction of the B++-tree and the performance of operations, like query, insertion, and deletion.There are two explicit factors in our experiments, which are the data size and the capacity .Thus, we conduct two sets of experiments by changing the data size and the capacity.For the one set of experiments, we change the data size while fixing the value of capacity.For the other set of experiments, we change the capacity while fixing the data size.

Construction of the B++-Tree.
Firstly, we test the performance of the construction of B++-tree.In this experiment, we change the data size and capacity to compare with the time needed to build a B++-tree.
In Figure 11(a), we vary the data size from 10,000 to 2,000,000, while fixing the capacity to 50.We denote the time of constructing a B++-tree as CT, which means the construction time.As we can see, when the data size is small, for example 10,000 and 100,000, their CTs are very small and similar.But with the growing of data size, CT is also increasing.The greater the size of data is, the more CT consumed.Because with the increment of data size, the structure of B++-tree will be more complicated.Therefore, the construction operation consumes more time.
In Figure 11(b), we vary the capacity of B++-tree from 10 to 100, while fixing the data size to 1,000,000.It is easy to find that CT is the shortest when the capacity  = 35.If the capacity is too small, the tree will be very high.If the capacity  is too big, the node will store too many intervals.Neither of these conditions contributes to the construction of the B++tree.Therefore, the capacity  = 35 is the most suitable for the construction of B++-tree, while the data size is 1,000,000.

Performance of Operations.
In this subsection, we test the performance of operations, which includes the query performance, the insertion performance, and the deletion performance.Then we analyze the reason of the performance and give the conclusion of experiments.
Query.Firstly we test the performance of query.Figure 12 gives the result of the experiment.We change  and the data size separately to conduct comparative experiments.We denote the time of traversing the leaf nodes as TT, which means the traversal time.
In Figure 12(a), we vary the data size from 10,000 to 2,000,000 while fixing the capacity to 50.From the figure, we can see that the greater the data size is, the bigger the TT is.Because the larger the data size is, the more leaf nodes the B++-tree has.Therefore, it takes more time to traverse the B++-tree.
In Figure 12(b), we vary the capacity  from 10 to 100 while fixing the data size to 1,000,000.The trend of TT is decreasing first but increasing again.Because when the capacity  is small, there will be too many leaf nodes in B++-tree, which cost much more time to traverse the B++-tree.When the capacity  is too big, the B++-tree will has too many leaf nodes.So when  = 35, the query performance is the best, while the data size is 1,000,000.
But the most important is that TT is very small all the time, which means query speed is very fast.Even the data size is 2 million; the query time is less than a second.This shows that the B++-tree we proposed is very suitable for the query operation.
Insertion.Secondly we investigate the insertion performance of B++-tree.Data insertion is the most common operation in constructing a B++-tree.We still test the insertion performance by changing the data size and capacity.We compare the time of inserting a bunch of data and the time of inserting a piece of data.The time of inserting data is called IT, which means the insertion time.
In Figure 13, we compare the time of inserting a bunch of data.In Figure 13(a), we vary the data size from 10,000 to 2,000,000 while fixing the capacity to 50 and the inserting data size to 5000.From the figure, we can see that with the data size increasing, the IT increases as well.Because  with the data size increasing, the B++-tree becomes more complicated.We need traverse more nodes to insert a record.In Figure 13(b), we vary the capacity from 10 to 100 while fixing the data size to 1,000,000 and the inserting data size to 5000.Same as the previous experiment of query, IT is the shortest when  = 35, because the structure of the B++-tree is the best at this capacity.When the capacity  = 35, B++-tree will not have too many nodes or too many intervals in a leaf node.
In Figure 14, we compare the time of inserting a piece of data.In Figure 14(a), we vary the data size from 10,000 to 2,000,000 while fixing the capacity to 50.We can see that the trend of Figure 14(a) is similar to Figure 13(a).It only takes 2 ms to insert a piece of data when the data size is 2,000,000.
In Figure 14(b), we vary the capacity from 10 to 100 while fixing the data size to 1,000,000.The time of inserting a piece of data is only about 1 ms.It is obvious that B++-tree is very efficient in data insertion.Deletion.Thirdly we investigate the deletion performance of B++-tree.Actually the principle of deletion is the same as the principle of insertion.Like the data insertion, we also test the deletion performance by changing the data size and capacity.We compare the time of deleting a bunch of data and the time of deleting a piece of data.The time of deleting data is called DT, which means the deletion time.
In Figure 15, we compare the time of deleting a bunch of data.In Figure 15(a), we vary the data size from 10,000 to 2,000,000 while fixing the capacity to 50 and the deleting data size to 5000.The result of Figure 15 is similar to Figure 13.With the increment of data size, the time of deletion increases as well, because of traversing more nodes.
In Figure 15(b), we vary the capacity from 10 to 100 while fixing the data size to 1,000,000 and the deleting data size to 5000.Same as Figure 13(b), DT is the shortest when  = 35.And the reason is the same as in Figure 13(b).
In Figure 16, we compare the time of deleting a piece of data.Figure 16 shows the same result as Figure 14.In Figure 16(a), we vary the data size from 10,000 to 2,000,000 while fixing the capacity to 50.The time of deleting a piece of data is very similar to the time of inserting a piece of data.
In Figure 16(b), we vary the capacity from 10 to 100 while fixing the data size to 1,000,000.The time of deleting a piece of data is only about 1 ms.The result shows that B++-tree is suitable for data deletion.Finally we give the conclusion of experiment.We combine the results of the previous experiments and put them into Figure 17.
For ease of viewing, we set the ordinate of Figure 17 to a logarithmic scale of 10.From the figure we can see IT is almost the same as DT, because those two operations are the same in principle.With the increment of data size, TT, CT, IT, and DT increase at the same time.But the growth rate of the TT is not very big.Because according to the description, the query operation only needs to traverse leaf nodes, which is very fast and efficient.Besides, we can see from Figure 17 that the time of query is very short and less than a second.
As we can see from our experiments, the B++-tree we proposed in this paper is well suited for calculating the maximal concurrency for our pricing model.

Conclusion
In this paper, we propose a dynamic pricing model, which takes into account using time, resource consumption, and maximum concurrency to make the price of cloud resources more reasonable for both users and providers.In order to calculate the maximal concurrency of all the users, we propose a new data structure, named B++-tree, which extends from B+tree and has additional information in leaf nodes.Besides, we introduce the insertion, deletion, split, and query operation of B++-tree, which can calculate the maximal concurrency.
Finally, we performed extensive experiments to study the performance of the construction, query, insertion, and deletion operations with different data sizes and capacities of B++-tree.The result of the experiments shows that the B++tree we proposed in this paper is well suited for calculating the maximal concurrency for our pricing model.We can complete the query operation on 10 million data in only 0.2 seconds.For the future work, we plan to find a much more reasonable pricing model which can take more factors into account.

Figure 3 :
Figure 3: An example of B+tree.

Figure 13 :
Figure 13: Experimental results of IT.

Figure 14 :Figure 15 :Figure 16 :
Figure 14: Experimental results of inserting a piece of data.

Figure 17 :
Figure 17: The trend of CT, TT, IT, and DT when varying the data sizes.
1) Start from the root node  (2) for each interval  ⋅  in .do (3) if interval  ⋅  intersects with 1) create new node  1 and  2 (2)  1 retains the first half intervals of the original node ;  2 retains the rest of intervals