Thursday, February 26, 2015

Search Engines: Comparison between Solr and Sphinx

Similarities:
  1.     Both Solr and Sphinx satisfy all of your requirements. They’re fast and designed to index and search large bodies of data efficiently.
  2.     Both have a long list of high-traffic sites using them
  3.     Both offer commercial support. (Solr, Sphinx)
  4.     Both offer client API bindings for several platforms/languages (Sphinx, Solr)
  5.     Both can be distributed to increase speed and capacity (Sphinx, Solr)

Solr Advantages:
  1.     Solr, being an Apache project, is obviously Apache2-licensed. Sphinx is GPLv2. This means that if you ever need to embed or extend (not just “use”) Sphinx in a commercial application, you’ll have to buy a commercial license (rationale)
  2.     Solr is easily embeddable in Java applications.
  3.     Solr is built on top of Lucene, which is a proven technology over 8 years old with a huge user base (this is only a small part). Whenever Lucene gets a new feature or speedup, Solr gets it too. Many of the devs committing to Solr are also Lucene committers.
  4.      Solr can be integrated with Hadoop to build distributed applications
  5.     Solr can be integrated with Nutch to quickly build a fully-fledged web search engine with crawler.
  6.     Solr can index proprietary formats like Microsoft Word, PDF, etc. Sphinx can’t.
  7.     Solr comes with a spell-checker out of the box.
  8.     Solr comes with facet support out of the box. Faceting in Sphinx takes more work.
  9.     Sphinx doesn’t allow partial index updates for field data.
  10.     In Sphinx, all document ids must be unique unsigned non-zero integer numbers. Solr doesn’t even require an unique key for many operations, and unique keys can be either integers or strings.
  11.     Solr supports field collapsing (currently as an additional patch only) to avoid duplicating similar results. Sphinx doesn’t seem to provide any feature like this.
  12.     While Sphinx is designed to only retrieve document ids, in Solr you can directly get whole documents with pretty much any kind of data, making it more independent of any external data store and it saves the extra roundtrip.
  13.     Solr, except when used embedded, runs in a Java web container such as Tomcat or Jetty, which require additional specific configuration and tuning (or you can use the included Jetty and just launch it with java -jar start.jar). Sphinx has no additional configuration.
Unless you need to extend the search functionality in any proprietary way, Sphinx is your best bet.

Sphinx Advantages:
  1.     Development and setup is faster
  2.     Much better (and faster) aggregation. This was the killer feature for us.
  3.     Not XML. This is what ultimately ruled out Solr for us. We had to return rather large result sets (think hundreds of results) and then aggregate them ourselves since Solr aggregation was lacking. The amount of time to serialize to and from XML just absolutely killed performance. For small results sets though, it was perfectly fine.
  4.     Best documentation I’ve seen in an open source app
  5.   Sphinx integrates more tightly with RDBMSs, especially MySQL
Source : http://stackoverflow.com/questions/1284083/choosing-a-stand-alone-full-text-search-server-sphinx-or-solr

Memcached Vs Redis, which one to pick for large web app?

Memcachedis a general-purpose distributed memory caching system. It is often used to speed up dynamic database-driven websites by caching data and objects in RAM to reduce the number of times an external data source (such as a database or API) must be read.

Redis is a flexible, open source and advanced key-value store. It is referred to as a “data structure server” where keys can contain strings, lists, hashes, sets and sorted sets of strings.

The main differences between them are listed below:

Installation:
Comparing ease of Installation Redis is much easier. No dependencies required.

Memory Usage:
For simple key-value pairs memcached is more memory efficient than Redis. If you use Redis hashes, then Redis is more memory efficient.

Persistence:
If you are using Memcached then data is lost with a restart and rebuilding cache is a costly process. On the other hand, Redis can handle persistent data. By default, Redis syncs data to the disk at least every 2 seconds.

Replication:
Memcached does not supports replication. Whereas Redis supports master-slave replication. It allows slave Redis servers to be exact copies of master servers. Data from any Redis server can replicate to any number of slaves.

Storage type:
Memcached stores variables in it’s memory. It retrieve any information directly from the servers memory instead of hitting the database again. On the other hand, Redis is like a database that resides in memory. It executes (read and write) a key/value pair from its database to return the resultset and all data resides in memory.Developers are using Redis also for real-time metrics, analytics.

Read/Write Speed:
Memcached is very good to handle high traffic websites. It can read lots of information at a time and give you back at a great response time. Redis can also handle high traffic on read but also can handle heavy writes as well.

Data Structure:
Memcached uses string and integer as data structure. Everything you save can be either one or the other. With integer, the only data manipulation you can do is adding or subtracting them. If you need to save arrays or objects, you will have to serialize them first and then save them. To read them back, you will need to un-serialize.
In comparison Redis has a stronger data structures. It can handle not only strings, integer but also binary-safe strings, lists of binary-safe strings, sets of binary-safe strings and sorted sets.

Key Length:
Memcached key length has a maximum of 250 bytes, whereas Redis key length has a maximum of 2GB.


If you need advanced data structures or disk-backed persistence, you should look into Redis. On the other hand, you might want to stick to Memcached for its simplicity, reliability and speed.

Thursday, September 18, 2014

Git Bash Common Command

- git checkout branch-name
- git pull origin branch-name
- git push origin branch-name
- git merge --no-ff
- git checkout -b
- git fetch
- get log
- for committing files on git-
- git add
- git add .   {for committing all files}
- git commit -m 'comment'

Friday, August 29, 2014

MySQL - Character Sets and Collations



A character set is a set of symbols and encodings. A collation is a set of rules for comparing characters in a character set. Let's make the distinction clear with an example of an imaginary character set.
Suppose that we have an alphabet with four letters: 'A', 'B', 'a', 'b'. We give each letter a number: 'A' = 0, 'B' = 1, 'a' = 2, 'c' = 3. The letter 'A' is a symbol, the number 0 is the encoding for 'A', and the combination of all four letters and their encodings is a character set.
Now, suppose that we want to compare two string values, 'A' and 'B'. The simplest way to do this is to look at the encodings: 0 for 'A' and 1 for 'B'. Because 0 is less than 1, we say 'A' is less than 'B'. Now, what we've just done is apply a collation to our character set. The collation is a set of rules (only one rule in this case): "compare the encodings." We call this simplest of all possible collations a binary collation.
But what if we want to say that the lowercase and uppercase letters are equivalent? Then we would have at least two rules: (1) treat the lowercase letters 'a' and 'b' as equivalent to 'A' and 'B'; (2) then compare the encodings. We call this a case-insensitive collation. It's a little more complex than a binary collation.

Using this example, you can change character set and collation for a MySQL database table(s).
Most likely you will be need to do this if you haven’t specified character set and collation at the time of database/table creation and default character set/collation applied are not desirable.

------------------------------------------------------------------------------------------------------------------

Setting MySQL default character set and collation in my.cnf

Below are settings for MySQL version 5.5.9 and onwards.
Put them in /etc/mysql/my.cnf is correct sections. Please be careful as some settings might be already present.
[mysqld]
character-set-server=utf8 
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
init_connect='SET collation_connection = utf8_unicode_ci' 
skip-character-set-client-handshake
 
Next, restart mysql and log into mysql shell:

mysql> show variables like "%character%";show variables like "%collation%";

Sample output as:
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

+----------------------+-----------------+
| Variable_name        | Value           |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database   | utf8_general_ci |
| collation_server     | utf8_general_ci |
+----------------------+-----------------+
3 rows in set (0.00 sec)

Checking current character set and collation for database/table/columns

For Database:

SELECT default_character_set_name, default_collation_name FROM information_schema.SCHEMATA  
WHERE schema_name = "databasename";
 
It will show output as:
+----------------------------+------------------------+
| default_character_set_name | default_collation_name |
+----------------------------+------------------------+
| latin1                     | latin1_swedish_ci      |
+----------------------------+------------------------+

For Tables:

SELECT T.table_name, T.table_collation, CCSA.character_set_name FROM information_schema.`TABLES` T,
information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA
WHERE CCSA.collation_name = T.table_collation
AND T.table_schema = "databasename";
 
Sample output as below:
+-----------------------------------------------------+-------------------+--------------------+
| table_name                                          | table_collation   | character_set_name |
+-----------------------------------------------------+-------------------+--------------------+
| rtc_wp_rtAccountToken                               | latin1_swedish_ci | latin1             |
| rtc_wp_rtAccountVerify                              | latin1_swedish_ci | latin1             |
| rtc_wp_rt_crm_mail_messageids                       | latin1_swedish_ci | latin1             |
| rtc_wp_w3tc_cdn_queue                               | latin1_swedish_ci | latin1             |
| gp_meta                                             | utf8_general_ci   | utf8               |
+-----------------------------------------------------+-------------------+--------------------+

For Columns:

SELECT table_name, column_name, character_set_name, collation_name FROM information_schema.`COLUMNS` C 
WHERE character_set_name != 'NULL' AND table_schema = "db_name"
 
Sample Output:
+------------------------+--------------+--------------------+-------------------+
| table_name             | column_name  | character_set_name | collation_name    |
+------------------------+--------------+--------------------+-------------------+
| rtc_wp_rtAccountToken  | accesstoken  | latin1             | latin1_swedish_ci |
| rtc_wp_rtAccountToken  | refreshtoken | latin1             | latin1_swedish_ci |
| rtc_wp_rtAccountVerify | email        | latin1             | latin1_swedish_ci |
| rtc_wp_rtAccountVerify | type         | latin1             | latin1_swedish_ci |
| rtc_wp_rtAccountVerify | code         | latin1             | latin1_swedish_ci |
+------------------------+--------------+--------------------+-------------------+

Converting character set and collations

MAKE BACKUP

We are serious. Just use mysqldump rather than regretting it later

Changing Database Character Sets and Collations

This is simplest:
ALTER DATABASE db_name CHARACTER SET utf8 COLLATE utf8_general_ci;
Replace your database name with db_name. Also after running query verify if database-level defaults are changed indeed.

Changing Tables Character Sets and Collations

Below is a syntax to covert character set ofwp_posts and wp_postmetatables.
alter table wp_posts convert to character set utf8 collate utf8_unicode_ci;
alter table wp_postmeta convert to character set utf8 collate utf8_unicode_ci;
If you want to covert all your MySQL tables, then run a command like below on database db_wordpress
mysql -e "SELECT concat('alter table ', TABLE_NAME , ' convert to character set utf8 collate utf8_unicode_ci;')
FROM information_schema.TABLES
WHERE table_schema = 'db_wordpress'
AND TABLE_COLLATION = 'latin1_swedish_ci'" |
tail -n+2 > collation.sql
After you run above query, check collation.sql content to verify if all rows are correct. If collation.sql is empty, you probably do not have a table using MyISAM engine.
If all looks good, run following to convert all mysql tables to InnoDB.
mysql db_wordpress < collation.sql

Changing Column Character Sets and Collations

Below is syntax to convert columns to utf8
alter table table_name change col_name col_name col_data_type character set utf8;
Please note that we have to use same col_name twice!
col_data_type can be found form a sql query like…
mysql> SELECT table_name, column_name, data_type, character_set_name, collation_name FROM information_schema.`COLUMNS` WHERE  table_schema = "db_name" AND table_name = "table_name" AND column_name = "col_name";
Sample output:
+--------------+--------------+-----------+
| table_name   | column_name  | data_type |
+--------------+--------------+-----------+
| wp_posts     | post_content | longtext  |
+--------------+--------------+-----------+
Example for wordpress’s wp_posts table
alter table wp_posts change post_content post_content LONGTEXT CHARACTER SET utf8;
Please be very careful for column conversion. Specially if you have non-english characters stored in database.

Source: https://rtcamp.com/tutorials/mysql/character-sets-collations/

Thursday, August 21, 2014

TortoiseGit - git not found

While this question is still hot... some nice people contributed lots of bugfixes to all three projects, so this is what I did to get TortoiseGit on Win7x64, previously failing on all combinations:
  1. install mSysGit (network installer) into C:\msysgit, it will download the source and compile it leaving you in a bash git prompt. Stable version: msysGit-netinstall-1.7.2.3-preview20100911.exe 13 sep
  2. install Git “preview” into C:\Program Files (x86)\Git, choose OpenSSH for ssh link Stable version: Git-1.7.2.3-preview20100911.exe 13 sep
  3. install tortoisegit into C:\Program Files\TortoiseGit, (x64 version) and configure it’s settings specifying the git path (C:\msysgit\bin) and menu integration. Stable version: TortoiseGit-1.5.6.0-64bit.msi 25 sep
This setup picked up my existing git repos made on WinXP x86 with older versions of the packages, and seems fairly stable and fully functional.

Source: http://stackoverflow.com/questions/1389281/tortoisegit-git-not-found

Thursday, July 31, 2014

Creating webservice server and client using NuSOAP



Brief description of NuSOAP:
NuSOAP is a rewrite of SOAPx4, provided by NuSphere and Dietrich Ayala. It is a set of PHP classes – no PHP extensions required – that allow developers to create and consume web services based on SOAP 1.1, WSDL 1.1 and HTTP 1.0/1.1.
Why using NuSOAP? PHP5 already has soapServer and soapClient implementation
  • it’s easy to implement and fast, no need to create WSDL document by yourself (this is my main reason why I choose NuSOAP)
  • compatibility, no special PHP extension need (I didn’t test it if still works on PHP4, but it does work flawlessly on PHP 5.0)
First, download NuSOAP from here: http://sourceforge.net/projects/nusoap/
The Server
We will create a SOAP server with two entry points (=function). One function take one parameter and output a string while the other one take two parameters and output a complex result (an array/struct). The codes with commentary:

Source1 : http://www.ahowto.net/php/creating-webservice-server-and-client-using-nusoap
Source2: http://www.scottnichol.com/nusoapprog.htm

Friday, July 11, 2014

The Ultimate Guide To UTF-8 and MySQL

The Ultimate Guide To UTF-8 and MySQL

How character encodings work in MySQL seem to continue baffle people, at least based on the number of questions posted on Stackoverflow. Read on if you have an application that still outputs funny text like “señor” or “se�or” where “señor” is expected.

The truth about text in MySQL

Strings in MySQL consist of an encoding marker and a list of bytes. The CHARSET function reads the encoding while HEX can be used to read bytes:
SELECT CHARSET("€"), HEX("€")
=> latin1, 80
This enables MySQL to use different encodings while working on a query. You can write a query that compares text columns in different encodings and returns the results where the text is the same, rather than the bytes that are stored.

I have everything set to utf8 and still the database gives me garbage!

That’s because of the MySQL client encoding. One query can return text in several different encodings, it’s unreasonable to expect the user software to check the encoding of each individual string. So all text returned by the MySQL client is encoded in only one encoding.
The fast and easy solution to encoding problems: set the MySQL client encoding.
How this is done depends on what you use to connect. If you work in PHP and the old MySQL functions you should use mysql_set_charset("utf8"). If you have an old version try mysql_query("SET NAMES utf8"). If you use MySQLi it would be mysqli_set_charset($link, "utf8") (or $link->set_charset("utf8") if you use the OO API).

What are the encodings in the tables good for, then?

When you create a table you can specify a character encoding for a column. It means how the MySQL server will convert text like “abc123″ to bytes that can be written to disk. The encoding affects two things:
  1. the range of characters that can be stored,  and
  2. the number of bytes the text will occupy on disk.
Popular encodings for storage include latin1 and utf8:
  • latin1: the characters that you can store cover most European languages, and the text occupies 1 byte per character.
  • utf8: you can store any(*) Unicode characters, and the text occupies from 1 to 3 bytes per character, depending on the character.
Other encodings exist, of course. For example latin2 has characters used in Eastern European languages. If you use ucs2 you can store any Unicode characters and the text occupies 2 bytes per character. If you are storing a lot of text in Japanese you may want to use ucs2 instead of utf8 because you are saving a third in the storage.
You can also specify a collation like utf8_general_ci for a column. It means how MySQL will sort the data. This affects indices and ORDER BY clauses. Cultures have different rules for alphabetic order: for example in Swedish Ä is the second to last letter of the alphabet, while in English it’s equivalent to A. So with Swedish collation you get a < b < ä and with English collation you get a = ä < b. Use the ordering your users expect. You can read more about collations in my other post.
What if you don’t specify an encoding and collation for the column? Then MySQL will use the default specified for the table, the database, or the server.

Converting encodings

Strings in MySQL consist of an encoding marker and a list of bytes. To convert strings from one encoding to another you can use the CONVERT(… USING …) function.  What CONVERT actually does is change both the marker and the bytes so that the resulting string is the same as the original; not very useful for fixing broken text.
The solution is stripping the encoding marker from the string before passing it to CONVERT. This is done by converting the string to “binary” first:
CONVERT(BINARY broken_text USING utf8)
I’ve written a detailed case study on fixing a particularly complicated MySQL encoding problem in another post.

Practical demonstration

Let’s create a table with columns in different encodings and fill it with some data.
CREATE TABLE test_encoding (
  utf8   varchar(4) CHARACTER SET utf8,
  latin1 varchar(4) CHARACTER SET latin1,
  latin2 varchar(4) CHARACTER SET latin2
);
INSERT INTO test_encoding (utf8,latin1,latin2) values ('A','A','A');
INSERT INTO test_encoding (utf8,latin1,latin2) values ('Ñ','Ñ','Ñ');
INSERT INTO test_encoding (utf8,latin1,latin2) values ('Ŕ','Ŕ','Ŕ');
INSERT INTO test_encoding (utf8,latin1,latin2) values ('☺','☺','☺');
INSERT INTO test_encoding (utf8,latin1,latin2) values ('€','€','€');
When you select the data from this table with select * from test_encoding you get the following results:
+------+--------+--------+
| utf8 | latin1 | latin2 |
+------+--------+--------+
| A    | A      | A      |
| Ñ    | Ñ      | ?      |
| Ŕ    | ?      | Ŕ      |
| ☺    | ?      | ?      |
| €    | €      | ?      |
+------+--------+--------+
Even though each column is encoded differently everything is still readable. This is thanks to the MySQL client encoding. The characters that could not be encoded are replaced with question marks: there is no Ñ in latin2, nor is there a Ŕ in latin1. The smiley face is not present in either.
The last line is interesting: the euro sign can be encoded in latin1 although technically it’s not really a latin1 character. This shows that MySQL’s latin1 is not really the standard ISO-8859-1 encoding, commonly known as “ISO latin 1″. In reality it is Windows-1252, the “Western European” encoding that also has curly quotes and other niceties where ISO-8859-1 has unprintable control characters.
To see that MySQL really is storing the columns in different encodings you could do this:
mysql> select utf8,hex(utf8),hex(latin1) from test_encoding;
+------+-----------+-------------+
| utf8 | hex(utf8) | hex(latin1) |
+------+-----------+-------------+
| A    | 41        | 41          |
| Ñ    | C391      | D1          |
| Ŕ    | C594      | 3F          |
| ☺    | E298BA    | 3F          |
| €    | E282AC    | 80          |
+------+-----------+-------------+
What happens when we compare two columns encoded differently?
mysql> select utf8,latin1 from test_encoding where utf8=latin1;
+------+--------+
| utf8 | latin1 |
+------+--------+
| A    | A      |
| Ñ    | Ñ      |
| €    | €      |
+------+--------+
MySQL knows that the character repertoire of latin1 is a subset of utf8, so it converts the latin1 column into unicode so that it can be compared. If however you try to compare latin1 with latin2 this is what happens:
mysql> select latin1,latin2 from test_encoding where latin1=latin2;
ERROR 1267 (HY000): Illegal mix of collations (latin1_bin,IMPLICIT) and (latin2_bin,IMPLICIT) for operation '='
Since neither latin1 and latin2 is a subset of the other, MySQL cannot compare the columns. To be able to compare them you have to convert at least one to unicode, e.g. by using CONVERT(.. USING ..):
select latin1, latin2 from test_encoding
where convert(latin1 using utf8)=latin2;
I hope this information is enough to solve any character encoding problems you may have with MySQL once and for all.
(*) Did I say utf8 can store any Unicode characters? That’s not really true. MySQL’s utf8 and ucs2 only store unicode from the basic multilingual plane (BMP), which includes “only” the characters U+0000 through U+FFFF. If you have MySQL 5.5 or later you have additional encodings to choose from: utf16, utf32, utf8mb4. These encodings You can read the details, as usual, in the official MySQL documentation.

Resource: http://jonisalonen.com/2012/ultimate-guide-to-utf8-and-mysql/