User Tools

Site Tools


intro

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

intro [2015/10/22 18:19] (current)
Line 1: Line 1:
 +====== Introduction ======
  
 +This article gives brief introduction into vyhodb. ​
 +
 +For practicing with vyhodb API use {{0.9.0:​vyhodb_getting_started.en.pdf|Getting Started}} document.\\
 +For getting more information about vyhodb API use {{0.9.0:​vyhodb_dev_guide.en.pdf|Developer'​s Guide}}.\\
 +For Function API details use {{0.9.0:​vyhodb_functions_reference.en.pdf|Functions API Reference}}.\\
 +For vyhodb administration and configuring see {{0.9.0:​vyhodb_admin_guide.en.pdf|Administrator'​s Guide}}.\\
 +All documents are available on [[docs|Documentation]] page.
 +
 +===== Network model =====
 +
 +Enterprise grade applications are usually dialing with complex domain model and sophisticated business logic. ​
 +Of course we can model almost everything in relation model, but it isn’t nature for relation model to 
 +dial with hierarchies,​ variable set of fields and relations, so we always have to align our 
 +domain model to relation model. Some projects even create their own frameworks for treating relation ​
 +databases as network ones.
 +
 +So, what are the basic concepts of vyhodb network model? There are five of them:
 +
 +  - **Space** - container of records (storage). Is used to create new records and retrieve record by its id.
 +  - **Record** – main concept, it is used to model some entity from real world. Similar to table’s row in database concept. Has unique identifier (long type) and contains fields.
 +  - **Field** – named value which is stored inside record.
 +  - **Link** – connect two records by child->​parent link.
 +  - **Indexes** – used for indexing children records of particular parent records to speed up searching.
 +
 +Let’s have a look at example. Picture below shows three records, connect by named links:
 +
 +{{ 0.9.0:​pics:​intro:​records.png?​576x204 }}
 +
 +vyhodb network model is schemaless, which means that application creates records, ​
 +connect them by links of any name, set fields of different names and different types. ​
 +vyhodb doesn’t have rules which could restrict your application model. ​
 +
 +Space API provides Java API for reading and modifying vyhodb data. Just a little code example, ​
 +to illustrate how simple it is:
 +
 +<code java5>
 +    Space space = …
 +
 +    Record root = space.getRecord(0L); ​                 // Retrieves record by id
 +        ​
 +    Record order1 = space.newRecord(); ​                 // Creates new record
 +    order1.setField("​Customer",​ "Some Customer 2"​); ​    // Sets field
 +    order1.setParent("​order2root",​ root); ​              // Creates link to root record
 +        ​
 +    Record order2 = space.newRecord(); ​          
 +    order2.setField("​Customer",​ "Other Customer 3"​); ​  
 +    order2.setParent("​order2root",​ root);
 +    order2.setParent("​relatedOrder",​ order1);
 +        ​
 +    // Iterates over child records
 +    for (Record order : root.getChildren("​order2root"​)) {
 +        System.out.println(order);​
 +    }
 +</​code>​
 +
 +So to sum up, vyhodb'​s network model is great, because:
 +
 +  * It models domain model in natural way
 +  * It is simple to dial with using Space API
 +  ​
 +===== ACID transactions =====
 +
 +We’ve seen a raise of no-SQL databases which have pretty cool options, like linear scaling ​
 +to thousands of nodes, large throughput, etc. But almost all of them refuse ​
 +**ACID** (//​Atomicity,​ Consistency,​ Isolation, Durability//​) properties.
 +
 +Does ACID really matter for enterprise application?​ Yes! It is crucial for business logic 
 +to keep data in consistent state whatever happens with system. And this is how vyhodb works. ​
 +It supports ACID transactions and transaction recovery in case of system crash.
 +
 +Transaction isolation is other major factor. Vyhodb supports **SERIALIZABLE** isolation level 
 +between transactions:​ each transaction runs independently. It means that you can write code 
 +without worry about how other running transactions can affect the current one (read phenomena).
 +
 +For performance reasons, vyhodb implements two transaction types: Read and Modify. ​
 +So custom application explicitly specifies which transaction is required.
 +
 +Let’s have a look at example below. Here we start vyhodb server in so called embedded mode 
 +(see further), open modify transaction and change data:
 +
 +<code java5>
 +  String LOG = "​C:​\\vyhodb-0.9.0\\storage\\vyhodb.log";​
 +  String DATA = "​C:​\\vyhodb-0.9.0\\storage\\vyhodb.log";​
 +        ​
 +  Properties props = new Properties(); ​               // Configures vyhodb storage
 +  props.setProperty("​storage.log",​ LOG);
 +  props.setProperty("​storage.data",​ DATA);
 +
 +  Server server = Server.start(props); ​               // Starts vyhodb in embedded mode
 +    ​
 +  TrxSpace space = server.startModifyTrx(); ​          // Opens Modify transaction
 +  Record record = space.getRecord(0L); ​               ​
 +  record.setField("​Description",​ "ACID matters!"​);​
 +  space.commit(); ​                                    // Commits transaction
 +    ​
 +  server.close(); ​                                    // Shutdowns vyhodb
 +</​code>​
 +
 +So, vyhodb:
 +
 +  * Supports ACID transactions
 +  * Provides SERIALIZABLE isolation which prevents read phenomena and simplifies application logic
 +  * Splits transaction into Read and Modify types for the sake of performance and lock optimization
 +  ​
 +===== Data Access and running modes =====
 +
 +Now I am going to explain how your application can interact with vyhodb. Well, there are two running modes with 
 +different interaction models:
 +
 +  - Embedded
 +  - Standalone
 +
 +==== Embedded mode ====
 +  ​
 +In embedded mode, your application starts vyhodb server in the same JVM, as shown on picture below:
 +
 +{{ 0.9.0:​pics:​intro:​running-mode.embedded.png?​576x182 }}
 +
 +We’ve seen example of how to start vyhdb in embedded mode in previous section. This is 
 +straightforward way to interact with vyhodb, but it isn’t convenient when many machines with your 
 +applications need access to vyhodb.
 +
 +==== Standalone mode ====
 +
 +Standalone mode is more common. In this mode, vyhodb server is running in its own JVM. It hosts so 
 +called RSI Services (RSI – remote service invocation),​ which have access to vyhodb by Space API. 
 +Your application connects to vyhodb server and invokes methods of RSI Services. RSI Services can be 
 +considered as stored procedures written on Java. Picture below illustrate it:
 +
 +{{ 0.9.0:​pics:​intro:​running-mode.standalone.png }}
 +
 +===== RSI =====
 +
 +Developing RSI Service is easy. Just do the following steps:
 +
 +  - Define service contract (Java interface) and add required annotations. Annotations define service implementation class and transaction types, which are opened by vyhodb during method invocation.
 +  - Create service implementation class.
 +  - Pack all classes into jar archive.
 +  - Deploy jar archive on vyhodb server (place it into **services** directory and restart vyhodb server).
 +  ​
 +Let’s have a look at code. Service contract:
 +
 +<code java5>
 +package com.vyhodb.intro;​
 +
 +import java.util.Collection;​
 +import com.vyhodb.rsi.Implementation;​
 +import com.vyhodb.rsi.Modify;​
 +import com.vyhodb.rsi.Read;​
 +
 +@Implementation(className="​com.vyhodb.intro.ServiceImpl"​)
 +public interface Service {
 +
 +    @Modify
 +    public long newOrder(String customerName);​
 +    ​
 +    @Read
 +    public Collection<​String>​ listCustomers();​
 +}
 +</​code>​
 +
 +Service implementation class
 +
 +<code java5>
 +package com.vyhodb.intro;​
 +
 +import java.util.ArrayList;​
 +import java.util.Collection;​
 +import com.vyhodb.space.Record;​
 +import com.vyhodb.space.ServiceLifecycle;​
 +import com.vyhodb.space.Space;​
 +
 +public class ServiceImpl implements Service, ServiceLifecycle {
 +
 +    private Space _space;
 +    ​
 +    @Override
 +    public void setSpace(Space space) {
 +        _space = space;
 +    }
 +
 +    @Override
 +    public long newOrder(String customerName) {
 +        Record root = _space.getRecord(0L);​
 +        ​
 +        Record order = _space.newRecord();​
 +        order.setField("​Customer",​ customerName);​
 +        order.setParent("​order2root",​ root);
 +        ​
 +        return order.getId();​
 +    }
 +
 +    @Override
 +    public Collection<​String>​ listCustomers() {
 +        ArrayList<​String>​ result = new ArrayList<>​();​
 +        ​
 +        Record root = _space.getRecord(0L);​
 +        for (Record order : root.getChildren("​order2root"​)) {
 +            String customerName = order.getField("​Customer"​); ​
 +            result.add(customerName); ​
 +        }
 +        ​
 +        return result;
 +    }
 +}
 +</​code>​
 +
 +And finally, client side code. It establishes connection to vyhodb and invokes service methods:
 +
 +<code java5>
 +package com.vyhodb.intro;​
 +
 +import com.vyhodb.rsi.Connection;​
 +import com.vyhodb.rsi.ConnectionFactory;​
 +    . . .
 +    String URL = "​tcp://​localhost:​47777";​
 +        ​
 +    try(Connection connection = ConnectionFactory.newConnection(URL)) {
 +            ​
 +        Service service = connection.getService(Service.class);​
 +            ​
 +        service.newOrder("​Customer 3");
 +        service.newOrder("​Customer 1");
 +        service.newOrder("​Customer 2");
 +           
 +        Collection<​String>​ customers = service.listCustomers();​
 +        System.out.println(customers);​
 +    }
 +</​code>​
 +
 +That’s all!
 +
 +So, what are the benefits of using RSI and standalone mode? A lot of them:
 +
 +  * You separate your business logic (in a form of RSI Services) and put it close to data.
 +  * One transaction per one method invocation. No network interactions during transaction. ​
 +  * Very simple RSI mechanism: no code generation, no schema, no xsd/xml, no service repositories.
 +  ​
 +===== Functions API =====
 +
 +Functions API is a library and approach which allows simple way for traversing over graph of records. ​
 +
 +It’s better to illustrate by example. We are going to implement code for printing OrderItem records ​
 +which refer to the Product record with specified name. Firstly, we'll show how to do it using for-each ​
 +cycles and after that how to solve the same task by using Functions API.
 +
 +Examples are based on the following data model:
 +
 +{{ 0.9.0:​pics:​intro:​sample-data-model.png }}
 +
 +Using **for-each** cycles:
 +
 +<code java5>
 +        String productName = "​Product 2";
 +        Record root = space.getRecord(0L);​
 +                ​
 +        for (Record product : root.getChildren("​product2root"​)) {
 +            if (productName.equals(product.getField("​Name"​))) {
 +                for (Record item : product.getChildren("​item2product"​)) {
 +                    System.out.println(item);​
 +                }
 +            }
 +        }
 +</​code>​
 +
 +Using Functions API (pay attention to static import directives):​
 +
 +<code java5>
 +import static com.vyhodb.f.CommonFactory.*;​
 +import static com.vyhodb.f.NavigationFactory.*;​
 +import static com.vyhodb.f.PredicateFactory.*; ​       ​
 +. . .
 +
 +        String productName = "​Product 2"; ​       ​
 +        Record root = space.getRecord(0L);​
 +                ​
 +        // Builds function
 +        F printf = 
 +        childrenIf("​product2root",​ fieldsEqual("​Name",​ productName),​
 +            children("​item2product", ​
 +                printCurrent()
 +            )
 +        );
 +   
 +        // Evaluates function
 +        printf.eval(root);​
 +</​code>​
 +
 +It looks more elegant, intuitive and simple, isn’t it?
 +
 +Main idea behind Functions API is that your application creates function (graph of function’s objects),
 + using static methods, and afterwards evaluate it. Code looks like program on function language (like LISP).
 + 
 +Functions API can be used in many situations: traversing records with filtering, printing graph of traversed records, modifying records, ​
 +calculating aggregate values (sum, min, max, …) and even creating Java object graph from records (see next section).
 +
 +All functions support serialization,​ so you can create function on client side and send it to RSI Service ​
 +for evaluation. However this approach has security issues.
 +
 +===== ONM API =====
 +
 +Space API with its records, field and links is good for using, but it would be better to read/write graph of 
 +java objects from/to vyhodb storage.
 +
 +ONM (**O**bject to **N**etwork model **M**apping) API is intended for this.
 +
 +In a nutshell it does:
 +
 +  * [[intro#​onm_reading|ONM Reading]] traverses over records and for each visited record create appropriate java objects and set references between objects. Traversing route is specified by functions (using Functions API).
 +  * [[intro#​onm_writing|ONM Writing]] traverses all objects in java object graph and updates corresponding records (creates new/​changes/​deletes).
 +  ​
 +Code example is better than thousands of words. At first, we define domain classes with annotations
 + ​(import directives, setters and getters are omitted to keep examples short). Annotations specify fields and 
 + link mappings. Domain classes are based on data model, shown in previous section.
 + 
 +Order class:
 +
 +<code java5>
 +@Record
 +public class Order {
 +    ​
 +    @Id
 +    private long id;
 +    ​
 +    @Field(fieldName="​Customer"​)
 +    private String customer;
 +    ​
 +    @Field(fieldName="​Date"​)
 +    private Date date;
 +    ​
 +    @Children(linkName="​item2order"​)
 +    private Collection<​Item>​ items;
 +    . . .
 +}
 +</​code>​
 +
 +Item class:
 +
 +<code java5>
 +@Record
 +public class Item {
 +
 +    @Id
 +    private long id = -1;
 +    ​
 +    @Field(fieldName="​Cost"​)
 +    private BigDecimal cost;
 +    ​
 +    @Parent(linkName="​item2order"​)
 +    private Order order;
 +    ​
 +    @Parent(linkName="​item2product"​)
 +    private Product product;
 +    . . .    ​
 +}
 +</​code>​
 +
 +Product class:
 +
 +<code java5>
 +@Record
 +public class Product {
 +
 +    @Id
 +    private long id = -1;
 +    ​
 +    @Field(fieldName="​Name"​)
 +    private String name;
 +    . . .
 +}
 +</​code>​
 +
 +Now we are going to read object graph. ​
 +
 +==== ONM Reading ====
 +
 +Code below creates ONM function, which traverses from record considered as **Order**
 + ​(passed to evaluation) to the **Item** records and further to related **Product** records.
 + 
 +For each visited record ONM function creates appropriate java object, fills its fields, ​
 +sets references to parent objects or adds child objects into collections:​
 +
 +<code java5>
 +import static com.vyhodb.f.NavigationFactory.*;​
 +import static com.vyhodb.onm.OnmFactory.*;​
 +. . .
 +        // Creates mapping information cache
 +        Mapping mapping = Mapping.newAnnotationMapping();​
 +        ​
 +        // Creates read function
 +        F onmReadF = 
 +        startRead(Order.class,​ mapping,
 +            children("​item2order",​
 +                parent("​item2product"​)
 +            )
 +        );
 +        ​
 +        // Retrieves record which correspond to Order
 +        Record orderRecord = getOrderRecord();​
 +        ​
 +        // Evaluates function. It traverses over records and creates ​
 +        // Order object with Item and Product objects
 +        Order order = (Order) onmReadF.eval(orderRecord);​
 +</​code>​
 +Note, that ONM Reading creates object graph, not an object tree.
 +
 +ONM neither generate auxiliary classes nor use code generation. ​ It facilitates java reflection. ​
 +ONM Reading creates the whole java object graph during function evaluation. No lazy loading.
 +
 +Because vyhodb is schemaless database, records don’t have types. Particular record can be used 
 +for instantiate objects of different classes, depending on traversal route and root object'​s class. ​
 +So you can have many class models for the same record graph.
 +
 +==== ONM Writing ====
 +
 +ONM Writing is pretty simple (**com.vyhodb.onm.Writer** class is used). Method **Writer#​write()** traverses over 
 +all java objects in passed graph and updates corresponding records in passed Space.
 +
 +<code java5>
 +        Space space = getSpace();
 +        Mapping mapping = Mapping.newAnnotationMapping();​
 +        ​
 +        Order order = buildObjects();​
 +                ​
 +        Writer.write(mapping,​ order, space);
 +</​code>​
 +
 +Benefits of using ONM API:
 +
 +  * Simple and flexible
 +  * Eager read; no lazy loading
 +  * No actions behind the scene: reading/​writing is fully controlled by application
 +  * No code/class generation: read objects are ordinary java objects
 +  * Reads object graph, not a tree
 +  ​
 +===== Administration =====
 +
 +vyhodb configuring and administration are really easy. There is only one configuration file and 
 +two storage files: data file (contains all data) and log file (transaction journal file). ​
 +Both storage files are growing automatically so you don’t have to worry about things like extending ​
 +table space etc.
 +
 +Administration tasks (like new storage creation, hot backup, restoration, ​
 +log file truncating, etc) are performed by command line utilities.
 +
 +As a production ready system, vyhodb supports the following features:
 +
 +  * Hot backups
 +  * Master - Slave replication
 +  * RSI balancer cluster (redistributes RSI invocation among many vyhodb servers)
 +  ​
intro.txt · Last modified: 2015/10/22 18:19 (external edit)

Page Tools