SlideShare uma empresa Scribd logo
1 de 48
Baixar para ler offline
Mnesia
2018/6/22
•
• Fusic
• Elixir React Golang PHP
• @kobatako_
• @kobatako
•
•
• CRUD
•
• Mnesia
• Erlang DBMS
• DB
• Schema
•
•
•
•
• Mnesia
• Erlang DBMS
• DB
• Schema
# iex --sname b --cookie bar
• Node sname a b
• cookie bar
# iex --sname a --cookie bar
Node A
Node B
• Node
iex(a@9fa43a09fbea)1> :mnesia.create_schema([node(), :"b@f2209c604096"])
• Schema
Mnesia.b@f2209c604096
Mnesia.a@9fa43a09fbea
• Node A
• Node B
• Node A Node B Schema
•
iex(b@f2209c604096)1> Node.list
[:a@9fa43a09fbea]
iex(a@9fa43a09fbea)1> Node.list
[]
iex(a@9fa43a09fbea)2> :mnesia.start
:ok
iex(a@9fa43a09fbea)3> Node.list
[:b@f2209c604096]
• Node A Mnesia
• Node B
iex(a@9fa43a09fbea)2> :mnesia.system_info
===> System info in version "4.15.3", debug level = none <===
opt_disc. Directory "/var/workspace/mnesia/data/snameA/Mnesia.a@9fa43a09fbea" is used.
use fallback at restart = true
running db nodes = []
stopped db nodes = [b@f2209c604096,a@9fa43a09fbea]
:no
Node A
• Mnesia
iex(b@f2209c604096)1> :mnesia.system_info
===> System info in version "4.15.3", debug level = none <===
opt_disc. Directory "/var/workspace/mnesia/data/snameB/Mnesia.b@f2209c604096" is used.
use fallback at restart = true
running db nodes = []
stopped db nodes = [b@f2209c604096,a@9fa43a09fbea]
:no
Node B
iex(a@9fa43a09fbea)4> :mnesia.start
:ok
iex(a@9fa43a09fbea)5> :mnesia.system_info
===> System info in version "4.15.3", debug level = none <===
opt_disc. Directory "/var/workspace/mnesia/data/snameA/Mnesia.a@9fa43a09fbea" is used.
use fallback at restart = false
running db nodes = [a@9fa43a09fbea]
stopped db nodes = [b@f2209c604096]
master node tables = []
remote = []
ram_copies = []
disc_copies = [schema]
disc_only_copies = []
[{a@9fa43a09fbea,disc_copies}] = [schema]
2 transactions committed, 0 aborted, 0 restarted, 0 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
:yes
Node A
• Mnesia
iex(b@f2209c604096)2> :mnesia.system_info
===> System info in version "4.15.3", debug level = none <===
opt_disc. Directory "/var/workspace/mnesia/data/snameB/Mnesia.b@f2209c604096" is used.
use fallback at restart = true
running db nodes = [a@9fa43a09fbea]
stopped db nodes = [b@f2209c604096]
:no
Node B
Node B Node A Mnesia
• Mnesia
iex(b@f2209c604096)6> :mnesia.start
:ok
iex(b@f2209c604096)7> :mnesia.system_info
===> System info in version "4.15.3", debug level = none <===
opt_disc. Directory "/var/workspace/mnesia/data/snameB/Mnesia.b@f2209c604096" is used.
use fallback at restart = false
running db nodes = [a@9fa43a09fbea,b@f2209c604096]
stopped db nodes = []
master node tables = []
remote = []
ram_copies = []
disc_copies = [schema]
disc_only_copies = []
[{a@9fa43a09fbea,disc_copies},{b@f2209c604096,disc_copies}] = [schema]
3 transactions committed, 0 aborted, 0 restarted, 2 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
:yes
Node B
• Mnesia
iex(a@9fa43a09fbea)7> :mnesia.create_table(Employee, [attributes:
[:emp_no, :name, :salary, :sex, :phone, :room_no]])
{:atomic, :ok}
iex(a@9fa43a09fbea)8> :mnesia.system_info
===> System info in version "4.15.3", debug level = none <===
opt_disc. Directory "/var/workspace/mnesia/data/snameA/Mnesia.a@9fa43a09fbea" is used.
use fallback at restart = false
running db nodes = [b@f2209c604096,a@9fa43a09fbea]
stopped db nodes = []
master node tables = []
remote = []
ram_copies = ['Elixir.Employee']
disc_copies = [schema]
disc_only_copies = []
[{a@9fa43a09fbea,disc_copies},{b@f2209c604096,disc_copies}] = [schema]
[{a@9fa43a09fbea,ram_copies}] = ['Elixir.Employee']
3 transactions committed, 0 aborted, 0 restarted, 5 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
:yes
Node A
Employee
•
iex(b@f2209c604096)8> :mnesia.system_info
===> System info in version "4.15.3", debug level = none <===
opt_disc. Directory "/var/workspace/mnesia/data/snameB/Mnesia.b@f2209c604096" is used.
use fallback at restart = false
running db nodes = [a@9fa43a09fbea,b@f2209c604096]
stopped db nodes = []
master node tables = []
remote = ['Elixir.Employee']
ram_copies = []
disc_copies = [schema]
disc_only_copies = []
[{a@9fa43a09fbea,disc_copies},{b@f2209c604096,disc_copies}] = [schema]
[{a@9fa43a09fbea,ram_copies}] = ['Elixir.Employee']
3 transactions committed, 0 aborted, 0 restarted, 5 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
:yes
Node B
B Employee
•
iex(a@9fa43a09fbea)9> :mnesia.create_table(Dept, [attributes: [:id, :name]])
{:atomic, :ok}
iex(a@9fa43a09fbea)10> :mnesia.create_table(Project, [attributes: [:id, :name]])
{:atomic, :ok}
iex(a@9fa43a09fbea)13> :mnesia.create_table(Manager, [type: :bag, attributes:
[:emp, :dept]])
{:atomic, :ok}
iex(a@9fa43a09fbea)14> :mnesia.create_table(AtDep, [attributes: [:emp, :dept_id]])
{:atomic, :ok}
iex(a@9fa43a09fbea)15> :mnesia.create_table(InProj, [type: :bag, attributes:
[:emp, :proj_name]])
{:atomic, :ok}
Node A
type bag ID
set ID
•
iex(a@9fa43a09fbea)5> :mnesia.system_info
===> System info in version "4.15.3", debug level = none <===
opt_disc. Directory "/var/workspace/mnesia/data/snameA/Mnesia.a@9fa43a09fbea" is used.
use fallback at restart = false
running db nodes = [b@f2209c604096,a@9fa43a09fbea]
stopped db nodes = []
master node tables = []
remote = []
ram_copies = ['Elixir.AtDep','Elixir.Dept','Elixir.InProj',
'Elixir.Manager','Elixir.Project']
disc_copies = [schema]
disc_only_copies = []
[{a@9fa43a09fbea,disc_copies},{b@f2209c604096,disc_copies}] = [schema]
[{a@9fa43a09fbea,ram_copies}] = ['Elixir.Dept','Elixir.Project',
'Elixir.Manager','Elixir.InProj',
'Elixir.AtDep']
7 transactions committed, 0 aborted, 0 restarted, 17 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
:yes
Node A
•
iex(b@f2209c604096)2> :mnesia.system_info
===> System info in version "4.15.3", debug level = none <===
opt_disc. Directory "/var/workspace/mnesia/data/snameB/Mnesia.b@f2209c604096" is used.
use fallback at restart = false
running db nodes = [a@9fa43a09fbea,b@f2209c604096]
stopped db nodes = []
master node tables = []
remote = ['Elixir.AtDep','Elixir.Dept','Elixir.InProj',
'Elixir.Manager','Elixir.Project']
ram_copies = []
disc_copies = [schema]
disc_only_copies = []
[{a@9fa43a09fbea,disc_copies},{b@f2209c604096,disc_copies}] = [schema]
[{a@9fa43a09fbea,ram_copies}] = ['Elixir.Dept','Elixir.Project',
'Elixir.Manager','Elixir.InProj',
'Elixir.AtDep']
3 transactions committed, 0 aborted, 0 restarted, 17 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
:yes
Node B
B
•
CRUD
CRUD
•
• Dirty Operations
def insert_emp(emp, dep_id, project_names) do
name = emp[:name]
#
fun = fn() ->
:mnesia.write({Employee, emp[:emp_no], emp[:name], emp[:salary], emp[:sex],
emp[:phone], emp[:room_no]})
at_dep = {AtDep, name, dep_id}
:mnesia.write(at_dep)
mk_proj(name, project_names)
end
#
:mnesia.transaction(fun)
end
insert
•
iex(a@9fa43a09fbea)3> insert_emp(%{emp_no: 104732, name: "klacke", salary: 7,
sex: :male, phone: 98108, room_no: {221, 015}}, "B/SFR", [:erlang, :mnesia, :otp])
Node A
insert insert_emp
•
iex(a@9fa43a09fbea)23> :mnesia.transaction(fn -> :mnesia.read({InProj, "klacke"}) end)
{:atomic,
[
{InProj, "klacke", :erlang},
{InProj, "klacke", :mnesia},
{InProj, "klacke", :otp}
]}
iex(a@9fa43a09fbea)24> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end)
{:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]}
iex(a@9fa43a09fbea)25> :mnesia.transaction(fn -> :mnesia.read({AtDep, "klacke"}) end)
{:atomic, [{AtDep, "klacke", "B/SFR"}]}
#
iex(a@9fa43a09fbea)11> :mnesia.read({Employee, 104732})
** (exit) {:aborted, :no_transaction}
(mnesia) mnesia.erl:351: :mnesia.abort/1
#
iex(a@9fa43a09fbea)11> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end)
{:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]}
Node A
read
•
iex(b@f2209c604096)17> :mnesia.transaction(fn -> :mnesia.read({InProj, "klacke"}) end)
{:atomic,
[
{InProj, "klacke", :erlang},
{InProj, "klacke", :mnesia},
{InProj, "klacke", :otp}
]}
iex(b@f2209c604096)18> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end)
{:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]}
iex(b@f2209c604096)19> :mnesia.transaction(fn -> :mnesia.read({AtDep, "klacke"}) end)
{:atomic, [{AtDep, "klacke", "B/SFR"}]}
Node B
Node A
•
Dirty Operations
Dirty Operations
iex(a@9fa43a09fbea)5> :mnesia.dirty_read(InProj, "klacke")
[
{InProj, "klacke", :erlang},
{InProj, "klacke", :mnesia},
{InProj, "klacke", :otp}
]
•
iex(a@9fa43a09fbea)32> :mnesia.dirty_write({Project, 1, "project01"})
:ok
iex(a@9fa43a09fbea)33> :mnesia.dirty_read(Project, 1)
[{Project, 1, "project01"}]
Dirty Operations
iex(a@9fa43a09fbea)36> :mnesia.dirty_write({Project, 2, "project02"})
:ok
iex(a@9fa43a09fbea)37> :mnesia.dirty_first(Project)
2
iex(a@9fa43a09fbea)38> :mnesia.dirty_next(Project, 2)
1
iex(a@9fa43a09fbea)39> :mnesia.dirty_next(Project, 1)
:”$end_of_table"
key
:”$end_of_table”
•
Node A B A
B
iex(a@9fa43a09fbea)1> :mnesia.start
:ok
iex(a@9fa43a09fbea)2> :mnesia.system_info
===> System info in version "4.15.3", debug level = none <===
opt_disc. Directory "/var/workspace/mnesia/data/snameA/Mnesia.a@9fa43a09fbea" is used.
use fallback at restart = false
running db nodes = [a@9fa43a09fbea]
stopped db nodes = [b@f2209c604096]
master node tables = []
remote = []
ram_copies = ['Elixir.AtDep','Elixir.Dept','Elixir.Employee',
'Elixir.InProj','Elixir.Manager','Elixir.Project']
disc_copies = [schema]
disc_only_copies = []
[{a@9fa43a09fbea,disc_copies}] = [schema]
[{a@9fa43a09fbea,ram_copies}] = ['Elixir.AtDep','Elixir.Dept','Elixir.InProj',
'Elixir.Project','Elixir.Employee',
'Elixir.Manager']
2 transactions committed, 0 aborted, 0 restarted, 0 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
:yes
Node A
Mnesia
•
#
iex(a@9fa43a09fbea)3> :mnesia.transaction(fn -> :mnesia.read({Employee, 104733}) end)
{:atomic, []}
# insert
iex(a@9fa43a09fbea)4> Sample.insert_emp(%{emp_no: 104732, name: "klacke", salary: 7,
sex: :male, phone: 98108, room_no: {221, 015}}, "B/SFR", [:erlang, :mnesia, :otp])
{:atomic, :ok}
#
iex(a@9fa43a09fbea)5> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end)
{:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]}
Node A
insert
•
#
iex(b@f2209c604096)2> Node.list
[]
# Mnesia
iex(b@f2209c604096)3> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end)
{:aborted, {:node_not_running, :b@f2209c604096}}
# Mnesia
iex(b@f2209c604096)4> :mnesia.start
:ok
#
iex(b@f2209c604096)5> Node.list
[:a@9fa43a09fbea]
#
iex(b@f2209c604096)6> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end)
{:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]}
Node B
B Mnesia
•
Node A
iex(a@9fa43a09fbea)10>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
^Croot@9fa43a09fbea:/var/workspace/mnesia/data/snameA#
Node A
Node
•
iex(b@f2209c604096)6> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end)
{:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]}
iex(b@f2209c604096)7>
nil
iex(b@f2209c604096)8> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end)
{:aborted, {:no_exists, Employee}}
Node B
🤔
iex(a@9fa43a09fbea)9> :mnesia.create_table(Dept, [attributes: [:id, :name]])
{:atomic, :ok}
iex(a@9fa43a09fbea)10> :mnesia.create_table(Project, [attributes: [:id, :name]])
{:atomic, :ok}
iex(a@9fa43a09fbea)13> :mnesia.create_table(Manager, [type: :bag, attributes:
[:emp, :dept]])
{:atomic, :ok}
iex(a@9fa43a09fbea)14> :mnesia.create_table(AtDep, [attributes: [:emp, :dept_id]])
{:atomic, :ok}
iex(a@9fa43a09fbea)15> :mnesia.create_table(InProj, [type: :bag, attributes:
[:emp, :proj_name]])
{:atomic, :ok}
•
• copies
iex(a@9fa43a09fbea)9> :mnesia.create_table(Dept, [ram_copies:
[:"b@f2209c604096"],attributes: [:id, :name]])
{:atomic, :ok}
iex(a@9fa43a09fbea)10> :mnesia.create_table(Project, [ram_copies:
[:"b@f2209c604096"],attributes: [:id, :name]])
{:atomic, :ok}
iex(a@9fa43a09fbea)13> :mnesia.create_table(Manager, [ram_copies:
[:"b@f2209c604096"],type: :bag, attributes: [:emp, :dept]])
{:atomic, :ok}
iex(a@9fa43a09fbea)14> :mnesia.create_table(AtDep, [ram_copies:
[:"b@f2209c604096"],attributes: [:emp, :dept_id]])
{:atomic, :ok}
iex(a@9fa43a09fbea)15> :mnesia.create_table(InProj, [ram_copies:
[:"b@f2209c604096"],type: :bag, attributes: [:emp, :proj_name]])
{:atomic, :ok}
• ram_copies Node table
ram_copies: [:"b@f2209c604096"]
•
iex(a@9fa43a09fbea)5> Sample.insert_emp(%{emp_no: 104732, name: "klacke", salary: 7,
sex: :male, phone: 98108, room_no: {221, 015}}, "B/SFR", [:erlang, :mnesia, :otp])
{:atomic, :ok}
Node A
Node B
iex(b@f2209c604096)3> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end)
{:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]}
Node A
Node B
iex(b@f2209c604096)4> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end)
{:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]}
🎉
iex(b@f2209c604096)3> Sample.insert_emp(%{emp_no: 104733, name: "hogehoge", salary: 7,
sex: :male, phone: 98109, room_no: {221, 015}}, "B/SFR", [:erlang, :mnesia, :otp])
{:atomic, :ok}
Node B
Node A
iex(a@9fa43a09fbea)6> :mnesia.transaction(fn -> :mnesia.read({Employee, 104733}) end)
{:atomic, [{Employee, 104733, "hogehoge", 7, :male, 98109, {221, 15}}]}
Node B
Node A
iex(a@9fa43a09fbea)7> :mnesia.transaction(fn -> :mnesia.read({Employee, 104733}) end)
{:aborted, {:no_exists, Employee}}
😱
ram_copies: [:"b@f2209c604096"]
•
ram_copies: [:"b@f2209c604096"]
•
ram_copies: [node(), :”b@f2209c604096”]
iex(b@f2209c604096)3> Sample.insert_emp(%{emp_no: 104733, name: "hogehoge", salary: 7,
sex: :male, phone: 98109, room_no: {221, 015}}, "B/SFR", [:erlang, :mnesia, :otp])
{:atomic, :ok}
Node B
Node A
iex(a@9fa43a09fbea)6> :mnesia.transaction(fn -> :mnesia.read({Employee, 104733}) end)
{:atomic, [{Employee, 104733, "hogehoge", 7, :male, 98109, {221, 15}}]}
Node B
Node A
iex(a@9fa43a09fbea)8> :mnesia.transaction(fn -> :mnesia.read({Employee, 104733}) end)
{:atomic, [{Employee, 104733, "hogehoge", 7, :male, 98108, {221, 15}}]}
🎉
• Mnesia 

Erlang
•
• EPMD Erlang Distribution
Protocol
Mnesiaで分散ノードに入門してみた

Mais conteúdo relacionado

Mais procurados

Elixir -Tolerância a Falhas para Adultos - GDG Campinas
Elixir  -Tolerância a Falhas para Adultos - GDG CampinasElixir  -Tolerância a Falhas para Adultos - GDG Campinas
Elixir -Tolerância a Falhas para Adultos - GDG CampinasFabio Akita
 
Writing DSLs with Parslet - Wicked Good Ruby Conf
Writing DSLs with Parslet - Wicked Good Ruby ConfWriting DSLs with Parslet - Wicked Good Ruby Conf
Writing DSLs with Parslet - Wicked Good Ruby ConfJason Garber
 
The Ring programming language version 1.5.4 book - Part 46 of 185
The Ring programming language version 1.5.4 book - Part 46 of 185The Ring programming language version 1.5.4 book - Part 46 of 185
The Ring programming language version 1.5.4 book - Part 46 of 185Mahmoud Samir Fayed
 
Py conkr 20150829_docker-python
Py conkr 20150829_docker-pythonPy conkr 20150829_docker-python
Py conkr 20150829_docker-pythonEric Ahn
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeStripe
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeMongoDB
 
Scala kansai summit-2016
Scala kansai summit-2016Scala kansai summit-2016
Scala kansai summit-2016Naoki Kitora
 
The Ring programming language version 1.4.1 book - Part 15 of 31
The Ring programming language version 1.4.1 book - Part 15 of 31The Ring programming language version 1.4.1 book - Part 15 of 31
The Ring programming language version 1.4.1 book - Part 15 of 31Mahmoud Samir Fayed
 
Http capturing
Http capturingHttp capturing
Http capturingEric Ahn
 
My SQL Idiosyncrasies That Bite OTN
My SQL Idiosyncrasies That Bite OTNMy SQL Idiosyncrasies That Bite OTN
My SQL Idiosyncrasies That Bite OTNRonald Bradford
 
Common Table Expressions in MariaDB 10.2
Common Table Expressions in MariaDB 10.2Common Table Expressions in MariaDB 10.2
Common Table Expressions in MariaDB 10.2Sergey Petrunya
 
The Ring programming language version 1.5.3 book - Part 46 of 184
The Ring programming language version 1.5.3 book - Part 46 of 184The Ring programming language version 1.5.3 book - Part 46 of 184
The Ring programming language version 1.5.3 book - Part 46 of 184Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 55 of 196
The Ring programming language version 1.7 book - Part 55 of 196The Ring programming language version 1.7 book - Part 55 of 196
The Ring programming language version 1.7 book - Part 55 of 196Mahmoud Samir Fayed
 
The Ring programming language version 1.5.4 book - Part 50 of 185
The Ring programming language version 1.5.4 book - Part 50 of 185The Ring programming language version 1.5.4 book - Part 50 of 185
The Ring programming language version 1.5.4 book - Part 50 of 185Mahmoud Samir Fayed
 
The Ring programming language version 1.3 book - Part 36 of 88
The Ring programming language version 1.3 book - Part 36 of 88The Ring programming language version 1.3 book - Part 36 of 88
The Ring programming language version 1.3 book - Part 36 of 88Mahmoud Samir Fayed
 
Encryption and Decryption using Tag Design
Encryption and Decryption using Tag Design Encryption and Decryption using Tag Design
Encryption and Decryption using Tag Design Joe Jiang
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixirKent Ohashi
 
Optimizing Queries with Explain
Optimizing Queries with ExplainOptimizing Queries with Explain
Optimizing Queries with ExplainMYXPLAIN
 
The Ring programming language version 1.9 book - Part 55 of 210
The Ring programming language version 1.9 book - Part 55 of 210The Ring programming language version 1.9 book - Part 55 of 210
The Ring programming language version 1.9 book - Part 55 of 210Mahmoud Samir Fayed
 

Mais procurados (20)

Elixir -Tolerância a Falhas para Adultos - GDG Campinas
Elixir  -Tolerância a Falhas para Adultos - GDG CampinasElixir  -Tolerância a Falhas para Adultos - GDG Campinas
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
 
Writing DSLs with Parslet - Wicked Good Ruby Conf
Writing DSLs with Parslet - Wicked Good Ruby ConfWriting DSLs with Parslet - Wicked Good Ruby Conf
Writing DSLs with Parslet - Wicked Good Ruby Conf
 
The Ring programming language version 1.5.4 book - Part 46 of 185
The Ring programming language version 1.5.4 book - Part 46 of 185The Ring programming language version 1.5.4 book - Part 46 of 185
The Ring programming language version 1.5.4 book - Part 46 of 185
 
Py conkr 20150829_docker-python
Py conkr 20150829_docker-pythonPy conkr 20150829_docker-python
Py conkr 20150829_docker-python
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at Stripe
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at Stripe
 
Scala kansai summit-2016
Scala kansai summit-2016Scala kansai summit-2016
Scala kansai summit-2016
 
The Ring programming language version 1.4.1 book - Part 15 of 31
The Ring programming language version 1.4.1 book - Part 15 of 31The Ring programming language version 1.4.1 book - Part 15 of 31
The Ring programming language version 1.4.1 book - Part 15 of 31
 
Http capturing
Http capturingHttp capturing
Http capturing
 
My SQL Idiosyncrasies That Bite OTN
My SQL Idiosyncrasies That Bite OTNMy SQL Idiosyncrasies That Bite OTN
My SQL Idiosyncrasies That Bite OTN
 
Explain
ExplainExplain
Explain
 
Common Table Expressions in MariaDB 10.2
Common Table Expressions in MariaDB 10.2Common Table Expressions in MariaDB 10.2
Common Table Expressions in MariaDB 10.2
 
The Ring programming language version 1.5.3 book - Part 46 of 184
The Ring programming language version 1.5.3 book - Part 46 of 184The Ring programming language version 1.5.3 book - Part 46 of 184
The Ring programming language version 1.5.3 book - Part 46 of 184
 
The Ring programming language version 1.7 book - Part 55 of 196
The Ring programming language version 1.7 book - Part 55 of 196The Ring programming language version 1.7 book - Part 55 of 196
The Ring programming language version 1.7 book - Part 55 of 196
 
The Ring programming language version 1.5.4 book - Part 50 of 185
The Ring programming language version 1.5.4 book - Part 50 of 185The Ring programming language version 1.5.4 book - Part 50 of 185
The Ring programming language version 1.5.4 book - Part 50 of 185
 
The Ring programming language version 1.3 book - Part 36 of 88
The Ring programming language version 1.3 book - Part 36 of 88The Ring programming language version 1.3 book - Part 36 of 88
The Ring programming language version 1.3 book - Part 36 of 88
 
Encryption and Decryption using Tag Design
Encryption and Decryption using Tag Design Encryption and Decryption using Tag Design
Encryption and Decryption using Tag Design
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixir
 
Optimizing Queries with Explain
Optimizing Queries with ExplainOptimizing Queries with Explain
Optimizing Queries with Explain
 
The Ring programming language version 1.9 book - Part 55 of 210
The Ring programming language version 1.9 book - Part 55 of 210The Ring programming language version 1.9 book - Part 55 of 210
The Ring programming language version 1.9 book - Part 55 of 210
 

Semelhante a Mnesiaで分散ノードに入門してみた

How I Built a Power Debugger Out of the Standard Library and Things I Found o...
How I Built a Power Debugger Out of the Standard Library and Things I Found o...How I Built a Power Debugger Out of the Standard Library and Things I Found o...
How I Built a Power Debugger Out of the Standard Library and Things I Found o...doughellmann
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+ConFoo
 
High Performance GPU computing with Ruby, Rubykaigi 2018
High Performance GPU computing with Ruby, Rubykaigi 2018High Performance GPU computing with Ruby, Rubykaigi 2018
High Performance GPU computing with Ruby, Rubykaigi 2018Prasun Anand
 
Асинхронность и многопоточность в Яндекс.Такси — Дмитрий Курилов
Асинхронность и многопоточность в Яндекс.Такси — Дмитрий КуриловАсинхронность и многопоточность в Яндекс.Такси — Дмитрий Курилов
Асинхронность и многопоточность в Яндекс.Такси — Дмитрий КуриловYandex
 
Strategies for refactoring and migrating a big old project to be multilingual...
Strategies for refactoring and migrating a big old project to be multilingual...Strategies for refactoring and migrating a big old project to be multilingual...
Strategies for refactoring and migrating a big old project to be multilingual...benjaoming
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)Wesley Beary
 
Elixir & Phoenix - fast, concurrent and explicit
Elixir & Phoenix - fast, concurrent and explicitElixir & Phoenix - fast, concurrent and explicit
Elixir & Phoenix - fast, concurrent and explicitTobias Pfeiffer
 
Beyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeBeyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeWim Godden
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the CloudWesley Beary
 
Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Platonov Sergey
 
Monitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
Monitoring Your ISP Using InfluxDB Cloud and Raspberry PiMonitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
Monitoring Your ISP Using InfluxDB Cloud and Raspberry PiInfluxData
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
More than syntax
More than syntaxMore than syntax
More than syntaxWooga
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsEleanor McHugh
 
Go Says WAT?
Go Says WAT?Go Says WAT?
Go Says WAT?jonbodner
 
Horizontally Scalable Relational Databases with Spark: Spark Summit East talk...
Horizontally Scalable Relational Databases with Spark: Spark Summit East talk...Horizontally Scalable Relational Databases with Spark: Spark Summit East talk...
Horizontally Scalable Relational Databases with Spark: Spark Summit East talk...Spark Summit
 

Semelhante a Mnesiaで分散ノードに入門してみた (20)

PythonOOP
PythonOOPPythonOOP
PythonOOP
 
How I Built a Power Debugger Out of the Standard Library and Things I Found o...
How I Built a Power Debugger Out of the Standard Library and Things I Found o...How I Built a Power Debugger Out of the Standard Library and Things I Found o...
How I Built a Power Debugger Out of the Standard Library and Things I Found o...
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
 
High Performance GPU computing with Ruby, Rubykaigi 2018
High Performance GPU computing with Ruby, Rubykaigi 2018High Performance GPU computing with Ruby, Rubykaigi 2018
High Performance GPU computing with Ruby, Rubykaigi 2018
 
Асинхронность и многопоточность в Яндекс.Такси — Дмитрий Курилов
Асинхронность и многопоточность в Яндекс.Такси — Дмитрий КуриловАсинхронность и многопоточность в Яндекс.Такси — Дмитрий Курилов
Асинхронность и многопоточность в Яндекс.Такси — Дмитрий Курилов
 
Czzawk
CzzawkCzzawk
Czzawk
 
Strategies for refactoring and migrating a big old project to be multilingual...
Strategies for refactoring and migrating a big old project to be multilingual...Strategies for refactoring and migrating a big old project to be multilingual...
Strategies for refactoring and migrating a big old project to be multilingual...
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
 
Elixir & Phoenix - fast, concurrent and explicit
Elixir & Phoenix - fast, concurrent and explicitElixir & Phoenix - fast, concurrent and explicit
Elixir & Phoenix - fast, concurrent and explicit
 
Beyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeBeyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the code
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloud
 
Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”
 
Monitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
Monitoring Your ISP Using InfluxDB Cloud and Raspberry PiMonitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
Monitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Explain this!
Explain this!Explain this!
Explain this!
 
More than syntax
More than syntaxMore than syntax
More than syntax
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord Migrations
 
Go Says WAT?
Go Says WAT?Go Says WAT?
Go Says WAT?
 
Tabledown
TabledownTabledown
Tabledown
 
Horizontally Scalable Relational Databases with Spark: Spark Summit East talk...
Horizontally Scalable Relational Databases with Spark: Spark Summit East talk...Horizontally Scalable Relational Databases with Spark: Spark Summit East talk...
Horizontally Scalable Relational Databases with Spark: Spark Summit East talk...
 

Mais de Takahiro Kobaru

Erlangでソフトウェアルータを作ってる話
Erlangでソフトウェアルータを作ってる話Erlangでソフトウェアルータを作ってる話
Erlangでソフトウェアルータを作ってる話Takahiro Kobaru
 
AppSyncをReactで使ってみた
AppSyncをReactで使ってみたAppSyncをReactで使ってみた
AppSyncをReactで使ってみたTakahiro Kobaru
 
SSOとか、SAMLとか、認証してみる
SSOとか、SAMLとか、認証してみるSSOとか、SAMLとか、認証してみる
SSOとか、SAMLとか、認証してみるTakahiro Kobaru
 
ReactでGraphQLを使っている
ReactでGraphQLを使っているReactでGraphQLを使っている
ReactでGraphQLを使っているTakahiro Kobaru
 
Phoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってるPhoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってるTakahiro Kobaru
 
GoとElixir、同時開発した時の気づき
GoとElixir、同時開発した時の気づきGoとElixir、同時開発した時の気づき
GoとElixir、同時開発した時の気づきTakahiro Kobaru
 
Elixir ライブラリ 「absinthe」でGraphQLに入門
Elixir ライブラリ 「absinthe」でGraphQLに入門Elixir ライブラリ 「absinthe」でGraphQLに入門
Elixir ライブラリ 「absinthe」でGraphQLに入門Takahiro Kobaru
 

Mais de Takahiro Kobaru (7)

Erlangでソフトウェアルータを作ってる話
Erlangでソフトウェアルータを作ってる話Erlangでソフトウェアルータを作ってる話
Erlangでソフトウェアルータを作ってる話
 
AppSyncをReactで使ってみた
AppSyncをReactで使ってみたAppSyncをReactで使ってみた
AppSyncをReactで使ってみた
 
SSOとか、SAMLとか、認証してみる
SSOとか、SAMLとか、認証してみるSSOとか、SAMLとか、認証してみる
SSOとか、SAMLとか、認証してみる
 
ReactでGraphQLを使っている
ReactでGraphQLを使っているReactでGraphQLを使っている
ReactでGraphQLを使っている
 
Phoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってるPhoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってる
 
GoとElixir、同時開発した時の気づき
GoとElixir、同時開発した時の気づきGoとElixir、同時開発した時の気づき
GoとElixir、同時開発した時の気づき
 
Elixir ライブラリ 「absinthe」でGraphQLに入門
Elixir ライブラリ 「absinthe」でGraphQLに入門Elixir ライブラリ 「absinthe」でGraphQLに入門
Elixir ライブラリ 「absinthe」でGraphQLに入門
 

Último

Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 

Último (20)

Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 

Mnesiaで分散ノードに入門してみた

  • 2. • • Fusic • Elixir React Golang PHP • @kobatako_ • @kobatako
  • 4.
  • 5. • Mnesia • Erlang DBMS • DB • Schema • •
  • 6. • • • Mnesia • Erlang DBMS • DB • Schema
  • 7.
  • 8. # iex --sname b --cookie bar • Node sname a b • cookie bar # iex --sname a --cookie bar Node A Node B • Node
  • 9. iex(a@9fa43a09fbea)1> :mnesia.create_schema([node(), :"b@f2209c604096"]) • Schema Mnesia.b@f2209c604096 Mnesia.a@9fa43a09fbea • Node A • Node B • Node A Node B Schema
  • 10. • iex(b@f2209c604096)1> Node.list [:a@9fa43a09fbea] iex(a@9fa43a09fbea)1> Node.list [] iex(a@9fa43a09fbea)2> :mnesia.start :ok iex(a@9fa43a09fbea)3> Node.list [:b@f2209c604096] • Node A Mnesia • Node B
  • 11. iex(a@9fa43a09fbea)2> :mnesia.system_info ===> System info in version "4.15.3", debug level = none <=== opt_disc. Directory "/var/workspace/mnesia/data/snameA/Mnesia.a@9fa43a09fbea" is used. use fallback at restart = true running db nodes = [] stopped db nodes = [b@f2209c604096,a@9fa43a09fbea] :no Node A • Mnesia iex(b@f2209c604096)1> :mnesia.system_info ===> System info in version "4.15.3", debug level = none <=== opt_disc. Directory "/var/workspace/mnesia/data/snameB/Mnesia.b@f2209c604096" is used. use fallback at restart = true running db nodes = [] stopped db nodes = [b@f2209c604096,a@9fa43a09fbea] :no Node B
  • 12. iex(a@9fa43a09fbea)4> :mnesia.start :ok iex(a@9fa43a09fbea)5> :mnesia.system_info ===> System info in version "4.15.3", debug level = none <=== opt_disc. Directory "/var/workspace/mnesia/data/snameA/Mnesia.a@9fa43a09fbea" is used. use fallback at restart = false running db nodes = [a@9fa43a09fbea] stopped db nodes = [b@f2209c604096] master node tables = [] remote = [] ram_copies = [] disc_copies = [schema] disc_only_copies = [] [{a@9fa43a09fbea,disc_copies}] = [schema] 2 transactions committed, 0 aborted, 0 restarted, 0 logged to disc 0 held locks, 0 in queue; 0 local transactions, 0 remote 0 transactions waits for other nodes: [] :yes Node A • Mnesia
  • 13. iex(b@f2209c604096)2> :mnesia.system_info ===> System info in version "4.15.3", debug level = none <=== opt_disc. Directory "/var/workspace/mnesia/data/snameB/Mnesia.b@f2209c604096" is used. use fallback at restart = true running db nodes = [a@9fa43a09fbea] stopped db nodes = [b@f2209c604096] :no Node B Node B Node A Mnesia • Mnesia
  • 14. iex(b@f2209c604096)6> :mnesia.start :ok iex(b@f2209c604096)7> :mnesia.system_info ===> System info in version "4.15.3", debug level = none <=== opt_disc. Directory "/var/workspace/mnesia/data/snameB/Mnesia.b@f2209c604096" is used. use fallback at restart = false running db nodes = [a@9fa43a09fbea,b@f2209c604096] stopped db nodes = [] master node tables = [] remote = [] ram_copies = [] disc_copies = [schema] disc_only_copies = [] [{a@9fa43a09fbea,disc_copies},{b@f2209c604096,disc_copies}] = [schema] 3 transactions committed, 0 aborted, 0 restarted, 2 logged to disc 0 held locks, 0 in queue; 0 local transactions, 0 remote 0 transactions waits for other nodes: [] :yes Node B • Mnesia
  • 15. iex(a@9fa43a09fbea)7> :mnesia.create_table(Employee, [attributes: [:emp_no, :name, :salary, :sex, :phone, :room_no]]) {:atomic, :ok} iex(a@9fa43a09fbea)8> :mnesia.system_info ===> System info in version "4.15.3", debug level = none <=== opt_disc. Directory "/var/workspace/mnesia/data/snameA/Mnesia.a@9fa43a09fbea" is used. use fallback at restart = false running db nodes = [b@f2209c604096,a@9fa43a09fbea] stopped db nodes = [] master node tables = [] remote = [] ram_copies = ['Elixir.Employee'] disc_copies = [schema] disc_only_copies = [] [{a@9fa43a09fbea,disc_copies},{b@f2209c604096,disc_copies}] = [schema] [{a@9fa43a09fbea,ram_copies}] = ['Elixir.Employee'] 3 transactions committed, 0 aborted, 0 restarted, 5 logged to disc 0 held locks, 0 in queue; 0 local transactions, 0 remote 0 transactions waits for other nodes: [] :yes Node A Employee •
  • 16. iex(b@f2209c604096)8> :mnesia.system_info ===> System info in version "4.15.3", debug level = none <=== opt_disc. Directory "/var/workspace/mnesia/data/snameB/Mnesia.b@f2209c604096" is used. use fallback at restart = false running db nodes = [a@9fa43a09fbea,b@f2209c604096] stopped db nodes = [] master node tables = [] remote = ['Elixir.Employee'] ram_copies = [] disc_copies = [schema] disc_only_copies = [] [{a@9fa43a09fbea,disc_copies},{b@f2209c604096,disc_copies}] = [schema] [{a@9fa43a09fbea,ram_copies}] = ['Elixir.Employee'] 3 transactions committed, 0 aborted, 0 restarted, 5 logged to disc 0 held locks, 0 in queue; 0 local transactions, 0 remote 0 transactions waits for other nodes: [] :yes Node B B Employee •
  • 17. iex(a@9fa43a09fbea)9> :mnesia.create_table(Dept, [attributes: [:id, :name]]) {:atomic, :ok} iex(a@9fa43a09fbea)10> :mnesia.create_table(Project, [attributes: [:id, :name]]) {:atomic, :ok} iex(a@9fa43a09fbea)13> :mnesia.create_table(Manager, [type: :bag, attributes: [:emp, :dept]]) {:atomic, :ok} iex(a@9fa43a09fbea)14> :mnesia.create_table(AtDep, [attributes: [:emp, :dept_id]]) {:atomic, :ok} iex(a@9fa43a09fbea)15> :mnesia.create_table(InProj, [type: :bag, attributes: [:emp, :proj_name]]) {:atomic, :ok} Node A type bag ID set ID •
  • 18. iex(a@9fa43a09fbea)5> :mnesia.system_info ===> System info in version "4.15.3", debug level = none <=== opt_disc. Directory "/var/workspace/mnesia/data/snameA/Mnesia.a@9fa43a09fbea" is used. use fallback at restart = false running db nodes = [b@f2209c604096,a@9fa43a09fbea] stopped db nodes = [] master node tables = [] remote = [] ram_copies = ['Elixir.AtDep','Elixir.Dept','Elixir.InProj', 'Elixir.Manager','Elixir.Project'] disc_copies = [schema] disc_only_copies = [] [{a@9fa43a09fbea,disc_copies},{b@f2209c604096,disc_copies}] = [schema] [{a@9fa43a09fbea,ram_copies}] = ['Elixir.Dept','Elixir.Project', 'Elixir.Manager','Elixir.InProj', 'Elixir.AtDep'] 7 transactions committed, 0 aborted, 0 restarted, 17 logged to disc 0 held locks, 0 in queue; 0 local transactions, 0 remote 0 transactions waits for other nodes: [] :yes Node A •
  • 19. iex(b@f2209c604096)2> :mnesia.system_info ===> System info in version "4.15.3", debug level = none <=== opt_disc. Directory "/var/workspace/mnesia/data/snameB/Mnesia.b@f2209c604096" is used. use fallback at restart = false running db nodes = [a@9fa43a09fbea,b@f2209c604096] stopped db nodes = [] master node tables = [] remote = ['Elixir.AtDep','Elixir.Dept','Elixir.InProj', 'Elixir.Manager','Elixir.Project'] ram_copies = [] disc_copies = [schema] disc_only_copies = [] [{a@9fa43a09fbea,disc_copies},{b@f2209c604096,disc_copies}] = [schema] [{a@9fa43a09fbea,ram_copies}] = ['Elixir.Dept','Elixir.Project', 'Elixir.Manager','Elixir.InProj', 'Elixir.AtDep'] 3 transactions committed, 0 aborted, 0 restarted, 17 logged to disc 0 held locks, 0 in queue; 0 local transactions, 0 remote 0 transactions waits for other nodes: [] :yes Node B B •
  • 20. CRUD
  • 22.
  • 23. def insert_emp(emp, dep_id, project_names) do name = emp[:name] # fun = fn() -> :mnesia.write({Employee, emp[:emp_no], emp[:name], emp[:salary], emp[:sex], emp[:phone], emp[:room_no]}) at_dep = {AtDep, name, dep_id} :mnesia.write(at_dep) mk_proj(name, project_names) end # :mnesia.transaction(fun) end insert •
  • 24. iex(a@9fa43a09fbea)3> insert_emp(%{emp_no: 104732, name: "klacke", salary: 7, sex: :male, phone: 98108, room_no: {221, 015}}, "B/SFR", [:erlang, :mnesia, :otp]) Node A insert insert_emp • iex(a@9fa43a09fbea)23> :mnesia.transaction(fn -> :mnesia.read({InProj, "klacke"}) end) {:atomic, [ {InProj, "klacke", :erlang}, {InProj, "klacke", :mnesia}, {InProj, "klacke", :otp} ]} iex(a@9fa43a09fbea)24> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end) {:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]} iex(a@9fa43a09fbea)25> :mnesia.transaction(fn -> :mnesia.read({AtDep, "klacke"}) end) {:atomic, [{AtDep, "klacke", "B/SFR"}]}
  • 25. # iex(a@9fa43a09fbea)11> :mnesia.read({Employee, 104732}) ** (exit) {:aborted, :no_transaction} (mnesia) mnesia.erl:351: :mnesia.abort/1 # iex(a@9fa43a09fbea)11> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end) {:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]} Node A read •
  • 26. iex(b@f2209c604096)17> :mnesia.transaction(fn -> :mnesia.read({InProj, "klacke"}) end) {:atomic, [ {InProj, "klacke", :erlang}, {InProj, "klacke", :mnesia}, {InProj, "klacke", :otp} ]} iex(b@f2209c604096)18> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end) {:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]} iex(b@f2209c604096)19> :mnesia.transaction(fn -> :mnesia.read({AtDep, "klacke"}) end) {:atomic, [{AtDep, "klacke", "B/SFR"}]} Node B Node A •
  • 28. Dirty Operations iex(a@9fa43a09fbea)5> :mnesia.dirty_read(InProj, "klacke") [ {InProj, "klacke", :erlang}, {InProj, "klacke", :mnesia}, {InProj, "klacke", :otp} ] • iex(a@9fa43a09fbea)32> :mnesia.dirty_write({Project, 1, "project01"}) :ok iex(a@9fa43a09fbea)33> :mnesia.dirty_read(Project, 1) [{Project, 1, "project01"}]
  • 29. Dirty Operations iex(a@9fa43a09fbea)36> :mnesia.dirty_write({Project, 2, "project02"}) :ok iex(a@9fa43a09fbea)37> :mnesia.dirty_first(Project) 2 iex(a@9fa43a09fbea)38> :mnesia.dirty_next(Project, 2) 1 iex(a@9fa43a09fbea)39> :mnesia.dirty_next(Project, 1) :”$end_of_table" key :”$end_of_table” •
  • 30.
  • 31. Node A B A B
  • 32. iex(a@9fa43a09fbea)1> :mnesia.start :ok iex(a@9fa43a09fbea)2> :mnesia.system_info ===> System info in version "4.15.3", debug level = none <=== opt_disc. Directory "/var/workspace/mnesia/data/snameA/Mnesia.a@9fa43a09fbea" is used. use fallback at restart = false running db nodes = [a@9fa43a09fbea] stopped db nodes = [b@f2209c604096] master node tables = [] remote = [] ram_copies = ['Elixir.AtDep','Elixir.Dept','Elixir.Employee', 'Elixir.InProj','Elixir.Manager','Elixir.Project'] disc_copies = [schema] disc_only_copies = [] [{a@9fa43a09fbea,disc_copies}] = [schema] [{a@9fa43a09fbea,ram_copies}] = ['Elixir.AtDep','Elixir.Dept','Elixir.InProj', 'Elixir.Project','Elixir.Employee', 'Elixir.Manager'] 2 transactions committed, 0 aborted, 0 restarted, 0 logged to disc 0 held locks, 0 in queue; 0 local transactions, 0 remote 0 transactions waits for other nodes: [] :yes Node A Mnesia •
  • 33. # iex(a@9fa43a09fbea)3> :mnesia.transaction(fn -> :mnesia.read({Employee, 104733}) end) {:atomic, []} # insert iex(a@9fa43a09fbea)4> Sample.insert_emp(%{emp_no: 104732, name: "klacke", salary: 7, sex: :male, phone: 98108, room_no: {221, 015}}, "B/SFR", [:erlang, :mnesia, :otp]) {:atomic, :ok} # iex(a@9fa43a09fbea)5> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end) {:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]} Node A insert •
  • 34. # iex(b@f2209c604096)2> Node.list [] # Mnesia iex(b@f2209c604096)3> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end) {:aborted, {:node_not_running, :b@f2209c604096}} # Mnesia iex(b@f2209c604096)4> :mnesia.start :ok # iex(b@f2209c604096)5> Node.list [:a@9fa43a09fbea] # iex(b@f2209c604096)6> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end) {:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]} Node B B Mnesia •
  • 36. iex(a@9fa43a09fbea)10> BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded (v)ersion (k)ill (D)b-tables (d)istribution ^Croot@9fa43a09fbea:/var/workspace/mnesia/data/snameA# Node A Node • iex(b@f2209c604096)6> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end) {:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]} iex(b@f2209c604096)7> nil iex(b@f2209c604096)8> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end) {:aborted, {:no_exists, Employee}} Node B
  • 37. 🤔
  • 38. iex(a@9fa43a09fbea)9> :mnesia.create_table(Dept, [attributes: [:id, :name]]) {:atomic, :ok} iex(a@9fa43a09fbea)10> :mnesia.create_table(Project, [attributes: [:id, :name]]) {:atomic, :ok} iex(a@9fa43a09fbea)13> :mnesia.create_table(Manager, [type: :bag, attributes: [:emp, :dept]]) {:atomic, :ok} iex(a@9fa43a09fbea)14> :mnesia.create_table(AtDep, [attributes: [:emp, :dept_id]]) {:atomic, :ok} iex(a@9fa43a09fbea)15> :mnesia.create_table(InProj, [type: :bag, attributes: [:emp, :proj_name]]) {:atomic, :ok} • • copies
  • 39. iex(a@9fa43a09fbea)9> :mnesia.create_table(Dept, [ram_copies: [:"b@f2209c604096"],attributes: [:id, :name]]) {:atomic, :ok} iex(a@9fa43a09fbea)10> :mnesia.create_table(Project, [ram_copies: [:"b@f2209c604096"],attributes: [:id, :name]]) {:atomic, :ok} iex(a@9fa43a09fbea)13> :mnesia.create_table(Manager, [ram_copies: [:"b@f2209c604096"],type: :bag, attributes: [:emp, :dept]]) {:atomic, :ok} iex(a@9fa43a09fbea)14> :mnesia.create_table(AtDep, [ram_copies: [:"b@f2209c604096"],attributes: [:emp, :dept_id]]) {:atomic, :ok} iex(a@9fa43a09fbea)15> :mnesia.create_table(InProj, [ram_copies: [:"b@f2209c604096"],type: :bag, attributes: [:emp, :proj_name]]) {:atomic, :ok} • ram_copies Node table ram_copies: [:"b@f2209c604096"] •
  • 40. iex(a@9fa43a09fbea)5> Sample.insert_emp(%{emp_no: 104732, name: "klacke", salary: 7, sex: :male, phone: 98108, room_no: {221, 015}}, "B/SFR", [:erlang, :mnesia, :otp]) {:atomic, :ok} Node A Node B iex(b@f2209c604096)3> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end) {:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]} Node A Node B iex(b@f2209c604096)4> :mnesia.transaction(fn -> :mnesia.read({Employee, 104732}) end) {:atomic, [{Employee, 104732, "klacke", 7, :male, 98108, {221, 15}}]} 🎉
  • 41.
  • 42. iex(b@f2209c604096)3> Sample.insert_emp(%{emp_no: 104733, name: "hogehoge", salary: 7, sex: :male, phone: 98109, room_no: {221, 015}}, "B/SFR", [:erlang, :mnesia, :otp]) {:atomic, :ok} Node B Node A iex(a@9fa43a09fbea)6> :mnesia.transaction(fn -> :mnesia.read({Employee, 104733}) end) {:atomic, [{Employee, 104733, "hogehoge", 7, :male, 98109, {221, 15}}]} Node B Node A iex(a@9fa43a09fbea)7> :mnesia.transaction(fn -> :mnesia.read({Employee, 104733}) end) {:aborted, {:no_exists, Employee}} 😱
  • 45. iex(b@f2209c604096)3> Sample.insert_emp(%{emp_no: 104733, name: "hogehoge", salary: 7, sex: :male, phone: 98109, room_no: {221, 015}}, "B/SFR", [:erlang, :mnesia, :otp]) {:atomic, :ok} Node B Node A iex(a@9fa43a09fbea)6> :mnesia.transaction(fn -> :mnesia.read({Employee, 104733}) end) {:atomic, [{Employee, 104733, "hogehoge", 7, :male, 98109, {221, 15}}]} Node B Node A iex(a@9fa43a09fbea)8> :mnesia.transaction(fn -> :mnesia.read({Employee, 104733}) end) {:atomic, [{Employee, 104733, "hogehoge", 7, :male, 98108, {221, 15}}]} 🎉
  • 46.
  • 47. • Mnesia 
 Erlang • • EPMD Erlang Distribution Protocol