<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Scalable and Robust Management of Dynamic Graph Data</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Alan G. Labouseur</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Paul W. Olsen Jr.</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Jeong-Hyon Hwang</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Department of Computer Science, University at Albany - State University of New York</institution>
          ,
          <country country="US">USA</country>
        </aff>
      </contrib-group>
      <abstract>
        <p>Most real-world networks evolve over time. This evolution can be modeled as a series of graphs that represent a network at di erent points in time. Our G* system enables e cient storage and querying of these graph snapshots by taking advantage of the commonalities among them. We are extending G* for highly scalable and robust operation. This paper shows that the classic challenges of data distribution and replication are imbued with renewed signi cance given continuously generated graph snapshots. Our data distribution technique adjusts the set of worker servers for storing each graph snapshot in a manner optimized for popular queries. Our data replication approach maintains each snapshot replica on a di erent number of workers, making available the most e cient replica con gurations for di erent types of queries.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. INTRODUCTION</title>
      <p>
        Real-world networks, including social networks and the
Web, constantly evolve over time [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ]. Periodic snapshots of
such a network can be represented as graphs where vertices
represent entities and edges represent relationships between
entities. These graph snapshots allow us to analyze the
evolution of a network over time by examining variations of
certain features, such as the distribution of vertex degrees
and clustering coe cients [
        <xref ref-type="bibr" rid="ref17">17</xref>
        ], network density [
        <xref ref-type="bibr" rid="ref20">20</xref>
        ], the size
of each connected component [
        <xref ref-type="bibr" rid="ref17 ref18">17, 18</xref>
        ], the shortest distance
between pairs of vertices [
        <xref ref-type="bibr" rid="ref20 ref23">20, 23</xref>
        ], and the centrality or
eccentricity of vertices [
        <xref ref-type="bibr" rid="ref23">23</xref>
        ]. Trends discovered by these analyses
play a crucial role in sociopolitical science, marketing,
security, transportation, epidemiology, and many other areas.
For example, when vertices represent people, credit cards,
and consumer goods, and edges represent ownership and
purchasing relationships, disruptions in degree distribution,
viewed over time, may indicate anomalous behavior, perhaps
even fraud.
      </p>
      <p>
        Several single-graph systems are available today: Google's
Pregel [
        <xref ref-type="bibr" rid="ref21">21</xref>
        ], Microsoft's Trinity [
        <xref ref-type="bibr" rid="ref29">29</xref>
        ], Stanford's GPS [
        <xref ref-type="bibr" rid="ref24">24</xref>
        ],
This work is supported by NSF CAREER Award
IIS-1149372.
the open source Neo4j [
        <xref ref-type="bibr" rid="ref22">22</xref>
        ], and others [
        <xref ref-type="bibr" rid="ref12 ref14 ref2 ref5 ref6 ref7">2, 5, 6, 7, 12, 14</xref>
        ].
They, however, lack support for e ciently managing large
graph snapshots. Our G* system [
        <xref ref-type="bibr" rid="ref13 ref27">13, 27</xref>
        ] e ciently stores
and queries graph snapshots on multiple worker servers by
taking advantage of the commonalities among snapshots.
DeltaGraph [
        <xref ref-type="bibr" rid="ref16">16</xref>
        ] achieves a similar goal. Our work is
complementary to DeltaGraph in that it focuses on new
challenges in data distribution and robustness in the context of
continuously creating large graph snapshots.
      </p>
      <p>Single-graph systems typically distribute the entirety of
a single graph over all workers to maximize the bene ts of
parallelism. When there are multiple graph snapshots,
however, distributing each snapshot on all workers may slow
down query execution. In particular, if multiple snapshots
are usually queried together, it is more advantageous to
store each snapshot on fewer workers as long as the
overall queried data are balanced over all workers. In this way,
the system can reduce network overhead (i.e., improve query
speed) while bene ting from high degrees of parallelism. We
present a technique that automatically adjusts the number
of workers in a manner optimized for popular queries.</p>
      <p>As implied above, there are vast di erences in execution
time depending on the distribution con gurations and the
number of snapshots queried together. Replication gives us,
in addition to enhanced system reliability, the opportunity
to utilize as many distribution con gurations as there are
replicas. G* constructs r replicas for each snapshot to
tolerate up to r 1 simultaneous worker failures. Our technique
classi es queries into r categories and optimizes the
distribution of each replica for one of the query categories.</p>
      <p>In this paper, we make the following contributions:
We de ne the problem of distributing graph snapshots
and present a solution that expedites queries by
adjusting the set of workers for storing each snapshot.
We provide a technique for adaptively determining
replica placement to improve system performance and
reliability.</p>
      <p>We present preliminary evaluation results that show
the e ectiveness of the above techniques.</p>
      <p>We discuss our research plans to complete the
construction of a highly scalable and reliable system for
managing large graph snapshots.</p>
      <p>The remainder of the paper is organized as follows:
Section 2 presents the research context and provides formal
de nitions of the problems studied in the paper. Sections 3
and 4 describe our new techniques for distributing and
replicating graph snapshots. Section 5 presents our preliminary
evaluation results. Section 6 discusses related work.
Section 7 concludes this paper.</p>
      <p>α
2.1
(3/4, {G1}), (4/5, {G2}), (5/6, {G3})
aveavragge
(1, 2, {G1, G2, G3}), (1, 1, {G1, G2, G3}), (2, 0, {G1}), (3, 1, {G2} (4, 2, {G3})
union
(1, 2, {G1,G2,G3}) (1, 1, {G1,G2,G3})
count_,sum count_sum
(a, 2, {G1,G2,G3}) (b, 1, {G1,G2,G3})
degree degree
(a, ..., {G1,G2,G3}) (b, ..., {G1,G2,G3})
vertex vertex
a c c c e
(2, 0, {G1}), (3, 1, {G2}), (4, 2, {G3}))
count_sum
(c, 0, {G1}), (d, 0, {G1, G2}), (c, 1, {G2, G3}), ...
degree
(c, ..., {G1}), (d, ..., {G1, G2}), (c, ...,{G2, G3}), ...</p>
      <p>vertex
b
{G1,G2,G3}
β</p>
      <p>b d
{G1,G2,G3}
γ</p>
      <p>d d f
{G1} {G1,G2} {G2,G3} {G3}</p>
    </sec>
    <sec id="sec-2">
      <title>BACKGROUND</title>
    </sec>
    <sec id="sec-3">
      <title>Summary of G*</title>
      <p>
        G* is a distributed system for managing large graph
snapshots that represent an evolving network at di erent points
in time [
        <xref ref-type="bibr" rid="ref13 ref27">13, 27</xref>
        ]. As Figure 1 shows, these graph snapshots
(e.g., G1, G2, and G3) are distributed over workers (e.g., ,
, and ) that both store and query the graph data assigned
to them. The master of the system (not shown in Figure 1)
transforms each submitted query into a network of
operators that process graph data on workers in a parallel fashion.
Our previous work on G* can be summarized as follows:
Graph Storage. In G*, each worker e ciently stores its
data by taking advantage of commonalities among graph
snapshots. Figure 2 shows how worker from Figure 1
incrementally stores its portion of snapshots G1, G2, and G3
on disk. The worker stores c1 and d1, the rst versions of
c and d, when it stores G1. When vertex c obtains a new
edge to e in G2, the worker stores c2, the second version of
c, which shares commonalities with the previous version and
also contains a new edge to e. When vertex d obtains a new
edge to f in G3, the worker stores d2, the second version of d
which contains a new edge to f . All of these vertex versions
are stored on disk only once regardless of how many graph
snapshots they belong to.
      </p>
      <p>
        To track all of these vertex versions, each worker
maintains a Compact Graph Index (CGI) that maps each
combination of vertex ID and graph ID onto the disk location
that stores the corresponding vertex version. For each vertex
version (e.g., c2), the CGI stores only one (vertex ID, disk
location) pair in a collection for the combination of
snapshots that contain that vertex version (e.g., fG2; G3g). In
this manner, the CGI handles only vertex IDs and disk
locations while all of the vertex and edge attributes are stored
on disk. Therefore, the CGI can be kept fully or mostly in
memory, enabling fast lookups and updates. To prevent the
CGI from becoming overburdened by managing too many
snapshot combinations, each worker automatically groups
snapshots and then separately indexes each group of
snapshots [
        <xref ref-type="bibr" rid="ref13 ref27">13, 27</xref>
        ].
      </p>
      <p>Query Processing. Like traditional database systems, G*
supports sophisticated queries using a data ow approach
where operators process data in parallel. To quickly process
queries on multiple graph snapshots, however, G* supports
special operators that share computations across snapshots.</p>
      <p>CGI
c1</p>
      <p>c2
c
disk
{G1} {G2,+G3}
c c e
{G1,+G2} {G3}
d d f
e1
e e
d1</p>
      <p>d2
d</p>
      <p>f1
f f</p>
      <p>
        Accelerating computation by distributing data over
multiple servers has been a popular approach in parallel
databases [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ] and distributed systems [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ]. Furthermore,
techniques for partitioning graphs to facilitate parallel
computation have also been developed [
        <xref ref-type="bibr" rid="ref15 ref24 ref25 ref26">15, 24, 25, 26</xref>
        ].
However, distributing large graph snapshots over multiple
workers raises new challenges. In particular, it is not desirable
to use traditional graph partitioning techniques which
consider only one graph at a time and incur high overhead
given a large number of vertices and edges. Solutions to
this problem must (re)distribute with low overhead graph
snapshots that are continuously generated and take
advantage of the property that query execution time depends on
both the number of snapshots queried and the distribution
of the graph snapshots as illustrated below.
      </p>
      <p>Example. Consider a scenario where each of 100
similarlysized graph snapshots contains approximately 1 million
vertices and 100 million edges. Assume also that the system
consists of one master and 100 workers. Table 1 compares
two snapshot distribution con gurations: Shared-Nothing,
where each of the 100 snapshots is stored on one
distinct worker, and Shared-Everything, where each snapshot
is evenly distributed over all of the 100 workers. For each of
these con gurations, two types of queries for computing the
PageRank of each vertex are executed: Query One
Snapshot, and Query All Snapshots. The explanations below are
based on our evaluation results (see Section 5 for details).</p>
      <p>In the case of Shared-Nothing, querying one snapshot
using only one worker takes 285 seconds (205 seconds to
construct the snapshot from disk and 80 seconds to run 20
iterations of PageRank). Querying all snapshots on all workers
in parallel takes the same amount of time. When the
SharedEverything con guration is used, querying one snapshot on
all workers takes approximately 22 seconds, mainly due to
network communications for the edges that cross worker
boundaries (the disk I/O and CPU costs correspond to only
205/100 seconds and 80/100 seconds, respectively, due to
the distribution of the snapshot over 100 workers). In this
con guration, querying 100 snapshots takes 2,205 seconds as
the PageRank of each vertex varies across graph snapshots,
thereby causing 100 times more message transmissions than
the previous case. This example shows the bene ts of
different snapshot distribution approaches for di erent types
of queries (e.g., Shared-Nothing for queries on all snapshots
and Shared-Everything for queries on one snapshot).
Formal De nition. Our ultimate goal is to keep track
of the popularity of graph snapshots and to optimize the
storage/distribution of unpopular snapshots for space e
ciency (Section 2.1) and popular snapshots for query speed.
In this paper, we focus on the problem of distributing
popular snapshots over workers in a manner that minimizes the
execution time of queries on these snapshots. This problem
can be formally de ned as follows:</p>
      <p>Problem 1. (Snapshot Distribution) Given a series
of graph snapshots fGi(Vi; Ei) : i = 1; 2; g, n workers,
and a set of queries Q on some or all of the snapshots, nd
a distribution fVi;w : i = 1; 2; ^ w = 1; 2; ; ng that
minimizes Pq2Q time(q; fVi;wg) where Vi;w denotes the set
of vertices that are from snapshot Gi(Vi; Ei) and that are
assigned to worker w, and time(q; fVi;wg) represents the
execution time of query q 2 Q on the distributed snapshots
fVi;wg satisfying (1) [nw=1Vi;w = Vi (i.e., the parts of a
snapshot on all workers cover the original snapshot) and (2)
Vi;w \ Vi;w0 = ; if w 6= w0 (i.e., workers are assigned disjoint
parts of a snapshot).</p>
      <p>Our solution to the above problem is presented in Section 3.
2.2.2</p>
      <p>Snapshot Replication</p>
      <p>
        There have been various techniques for replicating data to
improve availability and access speed [
        <xref ref-type="bibr" rid="ref11 ref28 ref8">8, 11, 28</xref>
        ]. A central
data replication challenge in G* is to distribute each replica
of a snapshot over a possibly di erent number of workers
to maximize both performance and availability. For each
query, the most bene cial replica also needs to be found
according to the characteristics of the query (e.g., the
number of snapshots queried). If two replicas of a graph
snapshot are distributed using the Shared-Nothing and
SharedEverything approaches, queries on a single snapshot should
use the Shared-Everything replica con guration rather than
the other. In practice, however, each query can access an
arbitrary number of graph snapshots (not necessarily one or
all), thereby complicating the above challenges. The
problem of replicating graph snapshots can be de ned as follows:
      </p>
      <p>Problem 2. (Snapshot Replication) Given a series
of graph snapshots fGi(Vi; Ei) : i = 1; 2; g, the degree of
replication r, n workers, and a set of queries Q on some
G2,1
G2,2
"
G3,1
G3,2
!
G2,1
G2,2
"
G1,1
G1,2
(a) Before Exchange
(b) After Exchange
or all of the snapshots, nd a replica distribution fVi;j;w :
i = 1; 2; ^ j = 1; 2; ; r ^ w = 1; 2; ; ng that
minimizes Pq2Q time(q; fVi;j;wg) where Vi;j;w denotes the
set of vertices that are from the jth replica Gi;j (Vi;j ; Ei;j )
of snapshot Gi(Vi; Ei) and that are assigned to worker w,
and time(q; fVi;j;wg) denotes the execution time of query q
on the distributed snapshot replicas fVi;j;wg satisfying (1)
[nw=1Vi;j;w = Vi;j = Vi for j = 1; 2; ; r, (i.e., the parts of
a snapshot replica on all workers cover the original replica),
(2) Vi;j;w \ Vi;j;w0 = ; if w 6= w0 (i.e., workers are assigned
disjoint parts of a snapshot replica), and (3) Vi;j;w \Vi;j0;w =
; if j 6= j0 (i.e., no worker w contains multiple copies of
a vertex and its edges, which tolerates r 1 simultaneous
worker failures).</p>
      <p>Section 4 presents our solution to the above problem.
3.</p>
    </sec>
    <sec id="sec-4">
      <title>GRAPH SNAPSHOT DISTRIBUTION</title>
      <p>
        As mentioned in Section 2.2.1, G* needs to store each
graph snapshot on an appropriate number of workers while
balancing the utilization of network and CPU resources.
In contrast to traditional methods for partitioning a static
graph [
        <xref ref-type="bibr" rid="ref15 ref25">15, 25</xref>
        ], G* must determine the location of each
vertex and its edges on the y in response to a continuous in ux
of data from external sources.
      </p>
      <p>Our dynamic data distribution approach meets the above
requirements. In this approach, each G* worker partitions
its graph data into segments with a certain maximum size
(e.g., 10GB) so that it can control its load by migrating
some segments to other workers (Section 3.1). Our
approach continuously routes incoming messages for updating
vertices and edges to appropriate workers with low latency
(Section 3.2). When a segment becomes full, G* splits that
segment into two that are similar in size while maintaining
data locality by keeping data accessed together within the
same segment (Section 3.3). It does all of the above while
supporting G*'s graph processing operators (Section 3.4).
3.1</p>
    </sec>
    <sec id="sec-5">
      <title>Load Balancing</title>
      <p>In G*, each worker periodically communicates with a
randomly chosen worker to balance graph data. Our key
principles in load balancing are to (1) maximize the bene ts of
parallelism by uniformly distributing data that are queried
together and (2) minimize network overhead by co-locating
data from the same snapshot. Consider Figure 3(a) where
three snapshots are partitioned into a total of 6
similarlysized segments. In this example, each of workers and
are assigned a segment from snapshot G1, is assigned two
segments from G2, and is assigned two segments from
G3. If snapshots G1 and G2 are frequently queried together
(see those shaded in Figure 3(a)), this snapshot
distribution leads to ine cient query execution due to imbalanced
workload between the workers and network communications
for the edges between G1;1 and G1;2. This problem can be
remedied by exchanging G1;1 and G3;1 between the workers,
which results in a balanced distribution of the data queried
together (i.e., G1 and G2) and localized processing of G1 on
and G2 on , respectively.</p>
      <p>Given a pair of workers, our technique estimates, for each
segment, the bene t of migrating that segment to the other
worker, and then performs the most bene cial migration.
This process is repeated a maximum number of times or
until the migration bene t falls below a prede ned threshold.
The bene t of migrating a segment is calculated by
multiplying the probability that the segment is queried with the
expected reduction in query time (i.e., the di erence
between expected query time before and after migration).</p>
      <p>For a set Si of segments on worker i and another set Sj of
segments on worker j, the expected query time is computed
as Pq2Qk p(q) time(q; Si; Sj) where Qk is a collection of k
popular query patterns, p(q) is the probability that query
pattern q is executed, and time(q; Si; Sj) denotes the
estimated duration of q given segment placements Si and Sj.</p>
      <p>
        Our technique obtains Qk (equivalently, k popular
combinations of segments queried together) as follows: Sort
segments from Si [ Sj in order of decreasing popularity.
Initialize Qk (for storing k popular query patterns) with the
rst segment. Then, for each of the remaining segments,
combine it with each element from Qk and insert the result
back into Qk. Whenever jQkj &gt; k, remove its least popular
element. We estimate the popularity of each combination
of segments by consolidating the counting synopses [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ] for
those segments. Whenever a query accesses a segment, the
associated synopsis is updated using the ID of the query.
      </p>
      <p>We compute time(q; Si; Sj) as max(c(q; Si); c(q; Sj)) +
c0(q; Si; Sj) where c(q; Si) is the estimated duration of
processing the segments from Si for query q, and c0(q; Si; Sj)
represents the estimated time for exchanging messages
between workers i and j for query q.
3.2</p>
    </sec>
    <sec id="sec-6">
      <title>Updates of Vertices and Edges</title>
      <p>Each new vertex (or any edge that emanates from the
vertex) is rst routed to a worker chosen according to the hash
value of the vertex ID. That worker assigns such a vertex to
one of its data segments while saving the (vertex ID, segment
ID) pair in an index similar to the CGI (Section 2.1). If a
worker receives an edge that emanates from an existing
vertex v, it assigns that edge to the segment that contains v. If
a worker w has created a segment S and then migrated it to
another worker w0 for load balancing reasons (Section 3.1),
worker w forwards the data bound to S to w0. To support
such data forwarding, each worker keeps track of the worker
location of each data segment that it has created before.
Updates of vertices and edges, including changes in their
attribute values, are handled as in the case of edge additions.
This assignment of graph data to workers is scalable because
it distributes the overhead of managing data over workers.
It also proceeds in a parallel, pipelined fashion without any
blocking operations.
3.3</p>
    </sec>
    <sec id="sec-7">
      <title>Splitting a Full Segment</title>
      <p>
        If the size of a data segment reaches the maximum (e.g.,
10GB), the worker that manages the segment creates a new
segment and then moves a half of the data from the
previous segment to the new segment. To minimize the number
of edges that cross segment boundaries, we use a traditional
graph partitioning method [
        <xref ref-type="bibr" rid="ref15">15</xref>
        ]. Whenever a segment is split
as above, the worker also updates the (vertex ID, segment
ID) pairs for all of the vertices migrated to the new segment.
This update process incurs relatively low overhead since the
index can usually be kept in memory as in the case of the
CGI (Section 2.1). If a worker splits a segment which was
obtained from another worker, it sends the update
information to the worker that originally created it in order to
enable data forwarding as mentioned in Section 3.2.
3.4
      </p>
    </sec>
    <sec id="sec-8">
      <title>Supporting Graph Processing Operators</title>
      <p>
        G*'s graph processing operators, such as those for
computing clustering coe cients, PageRank, or the shortest
distance between vertices, are usually instantiated on every
worker that stores relevant graph data [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ]. These
operators may exchange messages to compute a value for each
vertex (e.g., the current shortest distance from a source
vertex). If an operator needs to send a message to a vertex, the
message is rst sent to the worker whose ID corresponds to
the hash value of the vertex ID. This worker then forwards
the message to the worker that currently stores the vertex.
This forwarding mechanism is similar to that for handing
updates of vertices and edges (Section 3.2).
4.
      </p>
    </sec>
    <sec id="sec-9">
      <title>GRAPH SNAPSHOT REPLICATION</title>
      <p>
        G* masks up to r 1 simultaneous worker failures by
creating r copies of each graph data segment. As discussed in
Sections 2.2 and 3, the optimal distribution of each graph
snapshot over workers may vary with the number of
snapshots frequently queried together. Based on this
observation, we developed a new data replication technique that
speeds up queries by con guring the storage of replicas to
bene t di erent categories of queries. This approach uses
an online clustering algorithm [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] to classify queries into r
categories based on the number of graphs that they access.
It then assigns the j-th replica of each data segment to a
worker in a manner optimized for the j-th query category.
The master and workers support this approach as follows:
4.1
      </p>
    </sec>
    <sec id="sec-10">
      <title>Updates of Vertices and Edges</title>
      <p>Updates of vertices and edges are handled as described in
Section 3.2 except that they are routed to r data segment
replicas on di erent workers. For this reason, each worker
keeps a mapping that associates each segment ID with the
r workers that store a replica of the segment. Our approach
protects this mapping on worker w by replicating it on
workers (w+1)%n; (w+2)%n; ; (w+r 1)%n where n denotes
the number of workers. If a worker fails, the master assigns
another worker to take over.
4.2</p>
    </sec>
    <sec id="sec-11">
      <title>Splitting a Full Segment</title>
      <p>The replicas of a data segment are split in the same way
due to the use of a deterministic partition method. For each
vertex migrated from one data segment to another, the r
workers that keep track of that vertex update their (vertex
ID, segment ID) pairs accordingly.
4.3</p>
    </sec>
    <sec id="sec-12">
      <title>Query-Aware Replica Selection</title>
      <p>For each query, the master identi es the worker locations
of the data segment replicas to process. To this end, the</p>
      <sec id="sec-12-1">
        <title>Message passing (12-bytes/message)</title>
        <p>Disk I/O bandwidth
Snapshot construction in memory
PageRank iteration per snapshot
1M messages/sec
200 Mbytes/sec
200 seconds
4 seconds
master keeps track of the mapping between graph snapshots
and the data segments that constitute them. The master
also maintains the mapping between data segment replicas
and the workers that store them. Using these mappings, the
master selects one replica for each data segment such that
the overall processing load is uniformly distributed over a
large number of workers and the expected network overhead
is low. Next, as Figure 1 shows, the master instantiates
operators on these workers and starts executing the query.
4.4</p>
      </sec>
    </sec>
    <sec id="sec-13">
      <title>Load Balancing</title>
      <p>Each worker balances its graph data as explained in
Section 3. The only di erence is that whenever a query of
category j accesses a replica of a data segment, the counting
synopsis of the j-th replica of the data segment is updated
using the ID of the query (Section 3.1). In this way, the j-th
replica of each segment is assigned to a worker in a manner
optimized for query category j.</p>
    </sec>
    <sec id="sec-14">
      <title>PRELIMINARY EVALUATION</title>
      <p>This section presents our preliminary results obtained by
running G* on a six-node, 48-core cluster. In this cluster,
each machine has two Quad-Core Xeon E5430 2.67 GHz
CPUs, 16GB RAM, and a 2TB hard drive. We plan to
extend these experiments with more queries on larger data
sets in a bigger cluster (Section 7).</p>
      <p>To construct a realistic example in Section 2.2.1, we
measured the overhead of key operations summarized in Table 2.
In our evaluation, a worker was able to transmit up to 1
million messages to other workers within a second, although a
1Gbps connection may enable 10 million transmissions of
12-byte messages in theory. The reason behind this result
is that there is inherent overhead when writing and creating
message objects to and from TCP sockets in Java.
Furthermore, reading approximately 1Gbytes of data from disk to
construct a graph snapshot took 5 seconds. However,
constructing a snapshot in memory by creating 100 million edge
objects and registering them in an internal data structure
took approximately 200 seconds.</p>
      <p>In the next set of experiments, we created a series of 500
graph snapshots using a binary tree generator. Each
snapshot in the series was constructed by rst cloning the
previous snapshot and then inserting 20,000 additional vertices
and edges to the new graph. Therefore, the last graph in
the series contained 10 million vertices. We ran a query
that computes, for each graph, the distribution of the
shortest distances from the root to all other vertices. Table 3
shows, for the shortest distance query, the speedup achieved
by distributing the snapshots over more workers. The
highest speedup was achieved with 48 workers. This table also</p>
      <sec id="sec-14-1">
        <title>SSSP Query</title>
      </sec>
      <sec id="sec-14-2">
        <title>8.2 seconds</title>
        <p>80.5 seconds
19.2 seconds
53.2 seconds
shows that the relative bene t of data distribution (i.e., the
speedup relative to the number of workers) tends to decrease
with more workers. This is mainly due to increased network
tra c, which shows the importance of balancing CPU and
network resources in the context of continuously creating
large graph snapshots.</p>
        <p>The e ectiveness of two di erent distributions is
demonstrated in Table 4. If most queries access only the largest
snapshot, then it is bene cial to distribute that snapshot
over all workers to maximize query speed. On the other
hand, if all of the snapshots are queried together, our
approach stores each graph on a smaller subset of workers to
reduce network overhead. In this case, all of the workers
can still be used in parallel since the entire graph data is
distributed over all workers. The bene ts of distribution
con gurations are less pronounced in Table 4 than Table 1
due to a smaller number of message transmissions and fewer
workers. Table 4 also demonstrates the bene t of G* in
executing queries on multiple snapshots. In particular, the
time for processing 500 snapshots (e.g., 80.5 seconds) is only
up to 10 times longer than that for processing the largest
snapshot (e.g., 8.2 seconds) since the computations on the
largest snapshot are shared across smaller snapshots.
6.</p>
      </sec>
    </sec>
    <sec id="sec-15">
      <title>RELATED WORK</title>
      <p>In this section, we brie y summarize related research,
focusing on previous graph systems, data distribution, and
data replication.</p>
      <p>
        Previous Graph Systems. In contrast to systems which
process one graph at a time [
        <xref ref-type="bibr" rid="ref12 ref14 ref2 ref21 ref22 ref24 ref29 ref5 ref6 ref7">2, 5, 6, 7, 12, 14, 21, 22, 24,
29</xref>
        ], G* e ciently executes sophisticated queries on
multiple graph snapshots. G*'s bene ts over previous systems are
experimentally demonstrated in our prior work [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ].
DeltaGraph [
        <xref ref-type="bibr" rid="ref16">16</xref>
        ] and GraphChi [
        <xref ref-type="bibr" rid="ref19">19</xref>
        ] are promising systems for
dynamic graphs but do not directly address the data
distribution/replication issues considered in this paper.
Data Distribution. Traditional graph partitioning
techniques split a static graph into subgraphs in a manner that
minimizes the number of crossing edges [
        <xref ref-type="bibr" rid="ref15 ref25">15, 25</xref>
        ]. There are
also recent graph repartitioning schemes that observe
communication patterns and then move vertices to reduce
network overhead [
        <xref ref-type="bibr" rid="ref24 ref26">24, 26</xref>
        ]. In contrast to them, our technique
dynamically adjusts the number of workers that store each
graph snapshot according to the real-time in ux of graph
data and popular types of queries (Section 3).
      </p>
      <p>
        Data Replication. There has been extensive work on data
replication that focused on improving data availability and
performance [
        <xref ref-type="bibr" rid="ref11 ref28 ref8">8, 11, 28</xref>
        ]. Researchers developed techniques
for ensuring replica consistency [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ] and nding most
advantageous replica placement [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ]. Stonebraker et al. proposed
an approach that stores each database replica di erently,
optimized for a di erent query type [
        <xref ref-type="bibr" rid="ref28">28</xref>
        ]. While our
replication approach has some similarity in terms of high-level
ideas, it is substantially di erent in that it distributes each
graph snapshot over a di erent number of workers to speed
up di erent types of queries.
      </p>
    </sec>
    <sec id="sec-16">
      <title>CONCLUSIONS AND FUTURE WORK</title>
      <p>We presented G*, a scalable and robust system for storing
and querying large graph snapshots. G* tackles new data
distribution and replication challenges that arise in the
context of continuously creating large graph snapshots. Our
data distribution technique e ciently stores graph data on
the y using multiple worker servers in parallel. This
technique also gradually adjusts the number of workers that
store each graph snapshot while balancing network and CPU
overhead to maximize overall performance. Our data
replication technique maintains each graph replica on a di erent
number of workers, making available the most e cient
storage con gurations for various combinations of queries.</p>
      <p>We are working on full implementations of the techniques
presented in this paper to enable new experiments with
additional queries on larger data sets. We will analyze these
techniques to classify their complexity. We plan to look
into the challenges of scheduling groups of queries, dealing
with varying degrees of parallelism, resource utilization, and
user-generated performance preferences. We are exploring
failure recovery techniques for long-running queries while
exposing the tradeo between recovery speed and execution
time. We also want to study opportunities for more
granular splitting, merging, and exchanging of data at the vertex
and edge level rather than in large segments as discussed
in this paper. We intend to seek opportunities for gains in
execution speed at the expense of storage space by
segregating recent and popular \hot" data (which we could store
in a less compressed manner) from less popular \cold" data
(which could be highly compressed).</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>C. C.</given-names>
            <surname>Aggarwal</surname>
          </string-name>
          , J. Han,
          <string-name>
            <given-names>J</given-names>
            .
            <surname>Wang</surname>
          </string-name>
          , and
          <string-name>
            <given-names>P. S.</given-names>
            <surname>Yu</surname>
          </string-name>
          .
          <article-title>A Framework for Clustering Evolving Data Streams</article-title>
          .
          <source>In VLDB</source>
          , pages
          <volume>81</volume>
          {
          <fpage>92</fpage>
          ,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>Apache</given-names>
            <surname>Hama</surname>
          </string-name>
          . http://hama.apache.org.
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>B.</given-names>
            <surname>Bahmani</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Kumar</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Mahdian</surname>
          </string-name>
          , and
          <string-name>
            <surname>E. Upfal.</surname>
          </string-name>
          <article-title>PageRank on an Evolving Graph</article-title>
          .
          <source>In KDD</source>
          , pages
          <volume>24</volume>
          {
          <fpage>32</fpage>
          ,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>K. S.</given-names>
            <surname>Beyer</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P. J.</given-names>
            <surname>Haas</surname>
          </string-name>
          ,
          <string-name>
            <given-names>B.</given-names>
            <surname>Reinwald</surname>
          </string-name>
          ,
          <string-name>
            <given-names>Y.</given-names>
            <surname>Sismanis</surname>
          </string-name>
          , and
          <string-name>
            <given-names>R.</given-names>
            <surname>Gemulla</surname>
          </string-name>
          .
          <article-title>On Synopses for Distinct-Value Estimation Under Multiset Operations</article-title>
          .
          <source>In SIGMOD</source>
          , pages
          <volume>199</volume>
          {
          <fpage>210</fpage>
          ,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <surname>Cassovary</surname>
          </string-name>
          . Open Sourced from Twitter https://github.com/twitter/cassovary.
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>A.</given-names>
            <surname>Chan</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F. K. H. A.</given-names>
            <surname>Dehne</surname>
          </string-name>
          , and
          <string-name>
            <given-names>R.</given-names>
            <surname>Taylor</surname>
          </string-name>
          . CGMGRAPH/CGMLIB:
          <article-title>Implementing and Testing CGM Graph Algorithms on PC Clusters and Shared Memory Machines</article-title>
          . IJHPCA,
          <volume>19</volume>
          (
          <issue>1</issue>
          ):
          <volume>81</volume>
          {
          <fpage>97</fpage>
          ,
          <year>2005</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>R.</given-names>
            <surname>Chen</surname>
          </string-name>
          ,
          <string-name>
            <given-names>X.</given-names>
            <surname>Weng</surname>
          </string-name>
          ,
          <string-name>
            <given-names>B.</given-names>
            <surname>He</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Yang</surname>
          </string-name>
          .
          <article-title>Large Graph Processing in the Cloud</article-title>
          .
          <source>In SIGMOD</source>
          , pages
          <volume>1123</volume>
          {
          <fpage>1126</fpage>
          ,
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>Y.</given-names>
            <surname>Chen</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R. H.</given-names>
            <surname>Katz</surname>
          </string-name>
          , and
          <string-name>
            <given-names>J.</given-names>
            <surname>Kubiatowicz</surname>
          </string-name>
          .
          <article-title>Dynamic Replica Placement for Scalable Content Delivery</article-title>
          .
          <source>In IPTPS</source>
          , pages
          <volume>306</volume>
          {
          <fpage>318</fpage>
          ,
          <year>2002</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>J.</given-names>
            <surname>Dean</surname>
          </string-name>
          and
          <string-name>
            <given-names>S.</given-names>
            <surname>Ghemawat</surname>
          </string-name>
          .
          <source>MapReduce: Simpli ed Data Processing on Large Clusters. In OSDI</source>
          , pages
          <volume>137</volume>
          {
          <fpage>150</fpage>
          ,
          <year>2004</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <surname>D. DeWitt</surname>
          </string-name>
          , R. Gerber, G. Graefe,
          <string-name>
            <given-names>M.</given-names>
            <surname>Heytens</surname>
          </string-name>
          ,
          <string-name>
            <given-names>K.</given-names>
            <surname>Kumar</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Muralikrishna</surname>
          </string-name>
          .
          <article-title>Gamma - A High Performance Data ow Database Machine</article-title>
          .
          <source>In VLDB</source>
          , pages
          <volume>228</volume>
          {
          <fpage>237</fpage>
          ,
          <year>1986</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>J.</given-names>
            <surname>Gray</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Helland</surname>
          </string-name>
          ,
          <string-name>
            <surname>P. E. O'Neil</surname>
            ,
            <given-names>and D.</given-names>
          </string-name>
          <string-name>
            <surname>Shasha</surname>
          </string-name>
          .
          <article-title>The Dangers of Replication and a Solution</article-title>
          .
          <source>In SIGMOD</source>
          , pages
          <volume>173</volume>
          {
          <fpage>182</fpage>
          ,
          <year>1996</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <given-names>D.</given-names>
            <surname>Gregor</surname>
          </string-name>
          and
          <string-name>
            <given-names>A.</given-names>
            <surname>Lumsdaine. The Parallel</surname>
          </string-name>
          <string-name>
            <surname>BGL</surname>
          </string-name>
          :
          <article-title>A Generic Library for Distributed Graph Computations</article-title>
          .
          <source>In POOSC</source>
          ,
          <year>2005</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <surname>J.-H. Hwang</surname>
            ,
            <given-names>J.</given-names>
          </string-name>
          <string-name>
            <surname>Birnbaum</surname>
            ,
            <given-names>A.</given-names>
          </string-name>
          <string-name>
            <surname>Labouseur</surname>
            ,
            <given-names>P. W. Olsen</given-names>
          </string-name>
          <string-name>
            <surname>Jr.</surname>
            ,
            <given-names>S. R.</given-names>
          </string-name>
          <string-name>
            <surname>Spillane</surname>
            ,
            <given-names>J.</given-names>
          </string-name>
          <string-name>
            <surname>Vijayan</surname>
          </string-name>
          , and W.-S. Han. G*:
          <article-title>A System for E ciently Managing Large Graphs</article-title>
          .
          <source>Technical Report SUNYA-CS-12-04</source>
          , CS Department, University at Albany { SUNY,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [14]
          <string-name>
            <given-names>U.</given-names>
            <surname>Kang</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C. E.</given-names>
            <surname>Tsourakakis</surname>
          </string-name>
          , and
          <string-name>
            <given-names>C.</given-names>
            <surname>Faloutsos</surname>
          </string-name>
          .
          <article-title>PEGASUS: A Peta-Scale Graph Mining System</article-title>
          . In ICDM, pages
          <volume>229</volume>
          {
          <fpage>238</fpage>
          ,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [15]
          <string-name>
            <given-names>G.</given-names>
            <surname>Karypis</surname>
          </string-name>
          and
          <string-name>
            <given-names>V.</given-names>
            <surname>Kumar</surname>
          </string-name>
          .
          <article-title>Analysis of Multilevel Graph Partitioning</article-title>
          .
          <source>In SC, page 29</source>
          ,
          <year>1995</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          [16]
          <string-name>
            <given-names>U.</given-names>
            <surname>Khurana</surname>
          </string-name>
          and
          <string-name>
            <given-names>A.</given-names>
            <surname>Deshpande. E cient Snapshot</surname>
          </string-name>
          <article-title>Retrieval over Historical Graph Data</article-title>
          . CoRR, abs/1207.5777,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          [17]
          <string-name>
            <given-names>G.</given-names>
            <surname>Kossinets</surname>
          </string-name>
          and
          <string-name>
            <given-names>D. J.</given-names>
            <surname>Watts</surname>
          </string-name>
          .
          <article-title>Empirical Analysis of an Evolving Social Network</article-title>
          .
          <source>Science</source>
          ,
          <volume>311</volume>
          (
          <issue>5757</issue>
          ):
          <volume>88</volume>
          {
          <fpage>90</fpage>
          ,
          <year>2006</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          [18]
          <string-name>
            <given-names>R.</given-names>
            <surname>Kumar</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Novak</surname>
          </string-name>
          ,
          <article-title>and</article-title>
          <string-name>
            <given-names>A.</given-names>
            <surname>Tomkins</surname>
          </string-name>
          .
          <article-title>Structure and Evolution of Online Social Networks</article-title>
          .
          <source>In KDD</source>
          , pages
          <volume>611</volume>
          {
          <fpage>617</fpage>
          ,
          <year>2006</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          [19]
          <string-name>
            <given-names>A.</given-names>
            <surname>Kyrola</surname>
          </string-name>
          , G. Blelloch, and
          <string-name>
            <given-names>C.</given-names>
            <surname>Guestrin</surname>
          </string-name>
          .
          <article-title>Graphchi: large-scale graph computation on just a pc</article-title>
          .
          <source>In OSDI</source>
          , pages
          <volume>31</volume>
          {
          <fpage>46</fpage>
          ,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref20">
        <mixed-citation>
          [20]
          <string-name>
            <given-names>J.</given-names>
            <surname>Leskovec</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J. M.</given-names>
            <surname>Kleinberg</surname>
          </string-name>
          , and
          <string-name>
            <given-names>C.</given-names>
            <surname>Faloutsos</surname>
          </string-name>
          .
          <article-title>Graphs over Time: Densi cation Laws, Shrinking diameters and Possible Explanations</article-title>
          .
          <source>In KDD</source>
          , pages
          <volume>177</volume>
          {
          <fpage>187</fpage>
          ,
          <year>2005</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref21">
        <mixed-citation>
          [21]
          <string-name>
            <given-names>G.</given-names>
            <surname>Malewicz</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M. H.</given-names>
            <surname>Austern</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A. J. C.</given-names>
            <surname>Bik</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J. C.</given-names>
            <surname>Dehnert</surname>
          </string-name>
          , I. Horn,
          <string-name>
            <given-names>N.</given-names>
            <surname>Leiser</surname>
          </string-name>
          , and
          <string-name>
            <given-names>G.</given-names>
            <surname>Czajkowski.</surname>
          </string-name>
          <article-title>Pregel: A System for Large-Scale Graph Processing</article-title>
          .
          <source>In SIGMOD</source>
          , pages
          <volume>135</volume>
          {
          <fpage>146</fpage>
          ,
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref22">
        <mixed-citation>
          <article-title>[22] Neo4j The Graph Database</article-title>
          . http://neo4j.org/.
        </mixed-citation>
      </ref>
      <ref id="ref23">
        <mixed-citation>
          [23]
          <string-name>
            <given-names>C.</given-names>
            <surname>Ren</surname>
          </string-name>
          ,
          <string-name>
            <given-names>E.</given-names>
            <surname>Lo</surname>
          </string-name>
          ,
          <string-name>
            <given-names>B.</given-names>
            <surname>Kao</surname>
          </string-name>
          ,
          <string-name>
            <given-names>X.</given-names>
            <surname>Zhu</surname>
          </string-name>
          , and R. Cheng.
          <source>On Querying Historical Evolving Graph Sequences. PVLDB</source>
          ,
          <volume>4</volume>
          (
          <issue>11</issue>
          ):
          <volume>726</volume>
          {
          <fpage>737</fpage>
          ,
          <year>2011</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref24">
        <mixed-citation>
          [24]
          <string-name>
            <given-names>S.</given-names>
            <surname>Salihoglu</surname>
          </string-name>
          and
          <string-name>
            <given-names>J.</given-names>
            <surname>Widom. GPS: A Graph Processing</surname>
          </string-name>
          <article-title>System</article-title>
          .
          <source>In SSDBM</source>
          ,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref25">
        <mixed-citation>
          [25]
          <string-name>
            <given-names>K.</given-names>
            <surname>Schloegel</surname>
          </string-name>
          , G. Karypis, and
          <string-name>
            <given-names>V.</given-names>
            <surname>Kumar</surname>
          </string-name>
          .
          <article-title>Graph Partitioning for High Performance Scienti c Simulations</article-title>
          .
          <source>Technical Report TR 00-018</source>
          , Computer Science and Engineering, U. of Minnesota,
          <year>2000</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref26">
        <mixed-citation>
          [26]
          <string-name>
            <given-names>Z.</given-names>
            <surname>Shang</surname>
          </string-name>
          and
          <string-name>
            <given-names>J. X.</given-names>
            <surname>Yu</surname>
          </string-name>
          .
          <article-title>Catch the Wind: Graph Workload Balancing on Cloud</article-title>
          .
          <source>In ICDE</source>
          , pages
          <volume>553</volume>
          {
          <fpage>564</fpage>
          ,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref27">
        <mixed-citation>
          [27]
          <string-name>
            <given-names>S. R.</given-names>
            <surname>Spillane</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Birnbaum</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Bokser</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Kemp</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Labouseur</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P. W. Olsen</given-names>
            <surname>Jr.</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Vijayan</surname>
          </string-name>
          , and
          <string-name>
            <given-names>J.-H.</given-names>
            <surname>Hwang</surname>
          </string-name>
          .
          <article-title>A Demonstration of the G* Graph Database System</article-title>
          .
          <source>In ICDE</source>
          , pages
          <volume>1356</volume>
          {
          <fpage>1359</fpage>
          ,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref28">
        <mixed-citation>
          [28]
          <string-name>
            <given-names>M.</given-names>
            <surname>Stonebraker</surname>
          </string-name>
          et al.
          <article-title>C-Store: A Column-oriented DBMS</article-title>
          .
          <source>In VLDB</source>
          , pages
          <volume>553</volume>
          {
          <fpage>564</fpage>
          ,
          <year>2005</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref29">
        <mixed-citation>
          [29]
          <string-name>
            <surname>Trinity</surname>
          </string-name>
          . http://research.microsoft.com/en-us/projects/trinity/.
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>